shiro的一次认证多次授权
shiro的一次认证多次授权
springboot整合shiro(使用@Bean注解的形式配置javabean)
1.先在pom文件中引入shiro的jar包;
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
2.继承extends AuthorizingRealm 实现自己的realm中有两个重要得方法
备注:doGetAuthenticationInfo方法一般只会在登录的时候 UsernamePasswordToken token = new UsernamePasswordToken(userName, userPwd);
token.setRememberMe(true);
subject.login(token);
交给subject的login方法交给SecurityManager的login方法(这个方法中需要获得 AuthenticationInfo info;的验证信息,最终会realm中的getAuthenticationInfo方法,我们自定义的realm间接实现了这个方法,实现了自己的业务逻辑我们可以从数据库获取用户的身份信息进行验证)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection token) {
System.out.println("使用了自定义的realm,用户授权...");
// 获取用户名
// String userName = (String) principals.getPrimaryPrincipal();
// 依据用户名在数据库中查找权限信息
// 角色
List<String> roles = new ArrayList<>();
roles.add("admin");
roles.add("user");
// 权限
List<String> permissions = new ArrayList<>();
permissions.add("admin:select");
permissions.add("admin:delete");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermissions(permissions);
simpleAuthorizationInfo.addRoles(roles);
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
System.out.println("使用了自定义的realm,用户认证...");
System.out.println("用户名:" + ((UsernamePasswordToken) token).getUsername());
System.out.println("密码:" + new String(((UsernamePasswordToken) token).getPassword()));
// 模拟账号不存在
// if (true) {
// throw new UnknownAccountException();
// }
// 获取用户名
// String userName = (String) token.getPrincipal();
String userName = "123";
// 依据用户名去数据库查询
// 模拟从数据库中查询出来的散列值密码
String password = "123";
// 查询到了数据,验证密码是否正确
// 密码正确,认证通过
// 密码错误,认证失败
// 没有查询到数据,认证失败
// 模拟从数据库中获取salt
//String salt = "qwerty";
// 与UsernamePasswordToken(userName, password)进行比较
// 区别UsernamePasswordToken(userName, password)中的password是用户输入的密码,即没有加密过的密码
// SimpleAuthenticationInfo(userName, password, ByteSource.Util.bytes(salt), this.getName())中的password是数据库中的密码,即加密过后的密码
return new SimpleAuthenticationInfo(userName, password,this.getName());
}
3.配置shiroconfig
备注:这个配置类里面我们配置了一个shiro filter里面配置了url和对应的的过滤器,当我们使用注解进行权限控制的时候,我们需要开启注解支持,然后对注解做aop操作.subject中的hasrole,交给authorizer中的hasrole,然后authorizingrealm中的getauthorizationinfo方法中获取info,info中白包含用户的角色和权限集合,然后判断集合是否注解中的元数据,getauthorizationinfo中关联了cache,先从cache中获取info,获取不到的时候,通过自己定义realm中的重写dogetauthorizationinfo来获取info放到缓存中去,因为通过cache获取,所以我们实现了cachemanager和cache两个接口,从而实现了shiro和redis的整合。
/**
*
* @Title: createMyRealm
* @Description: 自定义的realm
* @return
*/
@Bean
public myrealm createMyRealm() {
myrealm myRealm = new myrealm();
return myRealm;
}
/**
*
* @Title: securityManager
* @Description: 注入自定义的realm
* @Description: 注意方法返回值SecurityManager为org.apache.shiro.mgt.SecurityManager
* ,不要导错包
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(myrealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
/**
*
* @Title: shirFilter
* @Description: Shiro 的Web过滤器
* @param securityManager
* @return
*/
@Bean({"shiroFilter"})
public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接,建议不配置,shiro认证成功自动到上一个请求路径
// shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面,指定没有权限操作时跳转页面
// shiroFilterFactoryBean.setUnauthorizedUrl("/403");
// 过滤器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被过滤的链接 顺序判断
// 过虑器链定义,从上向下顺序执行,一般将/**放在最下边
// 对静态资源设置匿名访问
// anon:所有url都都可以匿名访问
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logins", "anon");
// 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
// authc:所有url都必须认证通过才可以访问
filterChainDefinitionMap.put("/**", "user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//为了注解生效(开启注解)
@Bean({"authorizationAttributeSourceAdvisor"})
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
return new DefaultAdvisorAutoProxyCreator();
}
上一篇: shiro--Web集成
下一篇: Shiro之学习笔记(四)