第一步:
在pom.xml中添加依赖
<!-- 添加shiro依赖 begin-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- 添加shiro依赖 end-->
第二步:
添加MyShiroRealm类,继承AuthorizingRealm,重写doGetAuthenticationInfo和doGetAuthorizationInfo方法。
1、doGetAuthenticationInfo方法用于验证登录用户的账号和密码;当用户登录时,shiro的过滤器会自动处理post请求;如果验证失败,该方法返回null或者异常(带返回message),跳转到login的post链接。
2、doGetAuthorizationInfo方法用于获取用户的权限,权限存到SimpleAuthorizationInfo后返回。
注:doGetAuthenticationInfo这个方法是在用户登录的时候调用的也就是执行SecurityUtils.getSubject().login()的时候调用;(即:登录验证)而doGetAuthorizationInfo方法是在我们调用SecurityUtils.getSubject().isPermitted()这个方法时会调用doGetAuthorizationInfo(),而我们的@RequiresPermissions这个注解起始就是在执行SecurityUtils.getSubject().isPermitted()。
public class MyShiroRealm extends AuthorizingRealm{
/**
* 授权用户权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
System.out.println("doUserAuz11111");
//获取用户
User user = (User)SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取用户角色
Set<String> roleSet = new HashSet<String>();
roleSet.add("100002");
info.setRoles(roleSet);
//获取用户权限
Set<String> permissionSet = new HashSet<String>();
permissionSet.add("sys:acc:aaaa");
permissionSet.add("权限删除");
info.setStringPermissions(permissionSet);
return info;
}
/**
* 验证用户身份,如果验证失败,返回null或者异常(带返回message),跳转到login的post链接
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
System.out.println("doUserAucccccc11111");
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
String username = token.getUsername();
String password = String.valueOf(token.getPassword());
System.out.println("passW:"+password);
Map<String, Object> map = new HashMap<String, Object>();
map.put("nickname", username);
//密码进行加密处理 明文为 password+name
String paw = password+username;
String pawDES = paw;//MyDES.encryptBasedDes(paw);
map.put("pswd", pawDES);
User user = new User();
user.setId("112222");
user.setUserName(username);
user.setPassWord(pawDES);
// return new SimpleAuthenticationInfo(user, password, getName());
return null;
}
}
第三步:
添加ShiroConfiguration(@Configuration)类,配置shiroFilter、securityManager等。
@Configuration
public class ShiroConfiguration {
/**
* ShiroFilterFactoryBean 处理拦截资源文件问题。
* 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
* 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
*
* Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roles
*
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
System.out.println("sec11111");
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(myShiroRealm());
// 自定义缓存实现 使用redis
//securityManager.setCacheManager(cacheManager());
// 自定义session管理 使用redis
//securityManager.setSessionManager(sessionManager());
//注入记住我管理器;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
public MyShiroRealm myShiroRealm(){
System.out.println("getRealm11111");
return new MyShiroRealm();
}
/**
* cookie对象;
* @return
*/
public SimpleCookie rememberMeCookie(){
System.out.println("cookie11111");
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//<!-- 记住我cookie生效时间30天 ,单位秒;-->
simpleCookie.setMaxAge(2592000);
return simpleCookie;
}
/**
* cookie管理对象;记住我功能
* @return
*/
public CookieRememberMeManager rememberMeManager(){
System.out.println("cookieManager11111");
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
}
如果要开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),添加以下代码:
/**
* Shiro生命周期处理器 * @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能 * @return
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
网友评论