博客shiro学习笔记_0400_自定义Realm实现身份认证 介绍了认证,这里介绍授权。
1,仅仅通过配置文件来指定权限不够灵活且不方便。在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息 保存到了数据库中。所以需要从数据库中去获取相关的数据信息。可以使用 shiro 提供的JdbcRealm来实现,,也可以自定义realm来实现。使用jdbcRealm往往也不够灵活。所以在实际应用中大多数情况都是自定义Realm来实现。
2,自定义Realm 需要继承 AuthorizingRealm。
例子程序:
新建maven项目:
maven依赖:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency>
shiro.ini配置:
[main]
userRealm=com.lhy.realm.UserRealm
securityManager.realm=$userRealm
log4j.properties:
log4j.rootLogger=info, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
userRealm:
这里没有使用数据库,配置文件shiro.ini里不用配置[users]信息,因为这里在userRealm里的认证方法里的密码是模拟的,实际肯定会去数据库取。
package com.lhy.realm; import java.util.ArrayList; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; /** * 自定义Realm实现,该Realm类提供了两个方法: * 1,doGetAuthenticationInfo:获取认证信息 * 2,doGetAuthorizationInfo:获取权限信息 * @author Administrator * */ public class UserRealm extends AuthorizingRealm{ //realm接口的方法 @Override public String getName() { return "userRealm"; } //完成身份认证并返回认证信息 //如果身份认证失败,返回null @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { //获取用户输入的用户名 String username = (String)token.getPrincipal();//获取身份信息 System.out.println("username----"+username); //实际开发是调用service根据用户名去数据库查对应的密码 //假设获取的密码是1111 String password = "1111"; //Object principal, Object credentials, String realmName SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,getName()); return info; } //授权的信息 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //主的 身份信息 String username = principals.getPrimaryPrincipal().toString(); System.out.println("==========授权==========="); System.out.println("username ---"+username); //根据用户名到数据库查询当前用户对应的权限信息 ---这里模拟 List<String> permissions = new ArrayList<String>(); permissions.add("user:add"); permissions.add("user:delete"); permissions.add("user:update"); permissions.add("user:find"); /* * 实现了AuthorizationInfo接口的pojo,内部存的是权限和角色 */ SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //给当前用户分配权限 info.addStringPermissions(permissions); return info; } }
测试程序:
package com.lhy.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class userRealmDemo { public static void main(String[] args) { //1,创建SecurityManager工厂 读取shiro配置文件 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //2 通过securityManager工厂获取SecurityManager实例 SecurityManager securityManager = factory.getInstance(); //3 将SecurityManager 对象设置到运行环境 SecurityUtils.setSecurityManager(securityManager); //4 通过SecurityUtils获取主体subject Subject subject = SecurityUtils.getSubject(); try { //5.假设登录名是zhangsan 密码是1111 UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","1111"); //6,登录,进行用户身验证 subject.login(token); //通过subject判断用户是否通过验证 if(subject.isAuthenticated()){ System.out.println("用户登录成功!"); } } catch (UnknownAccountException e) { System.out.println("用户名或密码错误!"); e.printStackTrace(); }catch (IncorrectCredentialsException e) { System.out.println("用户名或密码错误!"); e.printStackTrace(); } System.out.println(subject.isPermittedAll("user:add","user:delete","user:update")); //7 退出 subject.logout(); } }