基于spring的shiro配置

Shiro继承spring

1.需要所有的springmvc.xml的配置

2.需要所有的web.xml的配置

3.需要所有的pom.xml的依赖

4.需要所有的spring.xml的配置

5.jdbc.properties文件

 

Web.xml配置

[html]  view plain  copy
  1. <!-- 配置shiro的代理过滤器   filter-name的名字和spring中bean的id一样 -->  
  2. <filter>  
  3.     <filter-name>shiroFilter</filter-name>  
  4.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  5.     <init-param>  
  6.         <param-name>targetFilterLifecycle</param-name>  
  7.         <param-value>true</param-value>  
  8.     </init-param>  
  9. </filter>  
  10. <filter-mapping>  
  11.     <filter-name>shiroFilter</filter-name>  
  12.     <url-pattern>/*</url-pattern>  
  13. </filter-mapping>  


 

spring.xml中配置realm

[html]  view plain  copy
  1. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  2. lt;!-- ref="myDbRealm" 自定义类MyDbRealm加注解@component继承AuthorizingRealm -->  
  3.    <property name="realm" ref="myDbRealm"/>  
  4. lt;/bean>  
  5. <!-- 后置处理器(用来注销securityManager) -->  
  6. lt;bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  


spring.xml中配置ini

 

[html]  view plain  copy
  1. <!-- spring 配置ini  bean的id与web.xml中filter-name一样-->  
  2.  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  3.     <property name="securityManager" ref="securityManager"/>  
  4.     <property name="loginUrl" value="/login.html"/>  
  5.     <property name="unauthorizedUrl" value="/un.html"/>  
  6.       
  7.     <property name="filterChainDefinitions">  
  8.         <value>  
  9.             /login.html = anon  
  10. /scu.jsp = authc  
  11.         </value>  
  12.     </property>  
  13. </bean>  

加入依赖:

[html]  view plain  copy
  1. 1. <dependency>    
  2. 2.     <groupId>org.apache.shiro</groupId>    
  3. 3.     <artifactId>shiro-spring</artifactId>    
  4. 4.     <version>1.4.0</version>    
  5. 5. </dependency>  

  

自定义filter实现动态配置url拦截

[html]  view plain  copy
  1. package cn.et.shiro.conf;  
  2.    
  3. import java.util.List;  
  4. import java.util.Set;  
  5. import java.util.regex.Pattern;  
  6.    
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.http.HttpServletRequest;  
  10.    
  11. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;  
  12. import org.apache.shiro.subject.Subject;  
  13. import org.apache.shiro.util.CollectionUtils;  
  14. import org.apache.shiro.web.filter.authz.AuthorizationFilter;  
  15. import org.springframework.beans.factory.annotation.Autowired;  
  16. import org.springframework.stereotype.Component;  
  17.    
  18. import cn.et.shiro.dao.UserMapper;  
  19. import cn.et.shiro.entity.Menu;  
  20.    
  21. @Component    
  22. public class MyFilter extends AuthorizationFilter {    
  23.         
  24.     @Autowired    
  25.     private ShiroFilterFactoryBean sffb;    
  26.     /**    
  27.      * 匹配指定过滤器规则的url    
  28.      * @param regex    
  29.      * @param url    
  30.      * @return    
  31.      */    
  32.     public static boolean matchUrl(String regex,String url){    
  33.          
  34.         regex=regex.replaceAll("/+", "/");    
  35.         if(regex.equals(url)){    
  36.             return true;    
  37.         }    
  38.         regex=regex.replaceAll("\\.", "\\\\.");    
  39.         // /login.html  /l*.html    
  40.         regex=regex.replaceAll("\\*", ".*");    
  41.         // /**/login.html  /a/b/login.html    
  42.         if(regex.indexOf("/.*.*/")>=0){    
  43.             regex=regex.replaceAll("/\\.\\*\\.\\*/", "((/.*/)+|/)");    
  44.         }    
  45.         System.out.println(regex+"----"+url);    
  46.         return Pattern.matches(regex, url);    
  47.     }    
  48.     @Autowired  
  49.     UserMapper userMapper;  
  50.     /**    
  51.      * 测试    
  52.      * @param args    
  53.      */    
  54.     public static void main(String[] args) {    
  55.         System.out.println(matchUrl("/**/s*.html","/t/g/login.html"));    
  56.     }      
  57.       
  58.     /**    
  59.      * isAccessAllowed用于判断当前url的请求是否能验证通过  如果验证失败 调用父类的onAccessDenied决定跳转到登录失败页还是授权失败页面    
  60.      */    
  61.     @Override    
  62.     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)    
  63.             throws Exception {  
  64.       
  65.         HttpServletRequest req=(HttpServletRequest)request;    
  66.         String contextPath=req.getContextPath();  
  67.         //获取用户访问的资源的路径  
  68.         String url=req.getRequestURI();  
  69.         url=url.split(contextPath)[1];  
  70.         //获取哪些url需要哪些认证  
  71.         //List<Menu> queryMenu=userMapper.queryMenuByUrl(url);  
  72.         List<Menu> queryMenu=userMapper.qieryMenu();  
  73.         if(queryMenu.size()==0){  
  74.             return false;  
  75.         }  
  76.         String urlAuth=null;  
  77.         for(Menu menu:queryMenu){  
  78.             if(matchUrl(menu.getMenuUrl(),url)){  
  79.             //取出权限  
  80.             urlAuth=menu.getMenuFilter();  
  81.             }  
  82.         }  
  83.         //通数据库没有配置当前url的授权  
  84.          
  85.          
  86.         if(urlAuth==null){    
  87.             return false;    
  88.         }    
  89.         //配置的过滤器是anon 直接放过    
  90.         if(urlAuth.startsWith("anon")){    
  91.             return true;    
  92.         }    
  93.         //配置的是authc 判断当前用户是否认证通过    
  94.         Subject subject = getSubject(request, response);    
  95.         if(urlAuth.startsWith("authc")){    
  96.             return subject.isAuthenticated();    
  97.         }    
  98.         //授权认证 也需要判断是否登录 没有登录返回 登录继续下面的验证    
  99.         boolean ifAuthc=subject.isAuthenticated();    
  100.         if(!ifAuthc)    
  101.             return ifAuthc;    
  102.         //如果是定义的roles过滤器  获取所有的roles 一般是roles[a,b]    
  103.         if(urlAuth.startsWith("roles")){    
  104.             String[] rolesArray=urlAuth.split("roles\\[")[1].split("\\]")[0].split(",");    
  105.             if (rolesArray == null || rolesArray.length == 0) {    
  106.                 return true;    
  107.             }    
  108.             Set<String> roles = CollectionUtils.asSet(rolesArray);    
  109.             return subject.hasAllRoles(roles);    
  110.         }    
  111.         if(urlAuth.startsWith("perms")){    
  112.             String[] perms=urlAuth.split("perms\\[")[1].split("\\]")[0].split(",");    
  113.             boolean isPermitted = true;    
  114.             if (perms != null && perms.length > 0) {    
  115.                 if (perms.length == 1) {    
  116.                     if (!subject.isPermitted(perms[0])) {    
  117.                         isPermitted = false;    
  118.                     }    
  119.                 } else {    
  120.                     if (!subject.isPermittedAll(perms)) {    
  121.                         isPermitted = false;    
  122.                     }    
  123.                 }    
  124.             }    
  125.     
  126.             return isPermitted;    
  127.         }    
  128.         return false;    
  129.     }    
  130.     
  131. }  


 

认证登录实现AuthorizingRealm 

[html]  view plain  copy
  1. package cn.et.shiro.conf;  
  2.    
  3. import java.util.Set;  
  4.    
  5. import org.apache.shiro.authc.AuthenticationException;  
  6. import org.apache.shiro.authc.AuthenticationInfo;  
  7. import org.apache.shiro.authc.AuthenticationToken;  
  8. import org.apache.shiro.authc.SimpleAccount;  
  9. import org.apache.shiro.authc.UsernamePasswordToken;  
  10. import org.apache.shiro.authz.AuthorizationInfo;  
  11. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  12. import org.apache.shiro.realm.AuthorizingRealm;  
  13. import org.apache.shiro.subject.PrincipalCollection;  
  14. import org.springframework.beans.factory.annotation.Autowired;  
  15. import org.springframework.stereotype.Component;  
  16.    
  17. import cn.et.shiro.dao.UserMapper;  
  18. import cn.et.shiro.entity.UserInfo;  
  19. @Component  
  20. public class MyDbRealm extends AuthorizingRealm {  
  21. @Autowired  
  22. UserMapper userMapper;  
  23. /**  
  24.  * 认证  
  25.  * 将登陆输入的用户名和密码和数据库中的用户名和密码对比  是否相等  
  26.  * 返回值null表示认证失败 非null认证通过  
  27.  */  
  28. @Override  
  29. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
  30. //获取从页面传入的token  
  31. UsernamePasswordToken upt=(UsernamePasswordToken)token;  
  32. //从数据库中查询userinfo对象  
  33. UserInfo queryUser=userMapper.queryUser(upt.getUsername());  
  34. //如果对象不为空,且密码相等 可以登录  
  35. if(queryUser!=null && queryUser.getPassword().equals(new String(upt.getPassword()))){  
  36. SimpleAccount sa=new SimpleAccount(upt.getUsername(),upt.getPassword(),"MyDbRealm");  
  37. return sa;  
  38. }  
  39. return null;  
  40. }  
  41. /**  
  42.  * 获取当前文件的授权数据  
  43.  * 将当前用户在数据库的角色和权限 加载到AuthorizationInfo  
  44.  * 默认在进行授权认证的调用 检查权限调用checkRole checkPerm  
  45.  */  
  46. @Override  
  47. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  48. //获取用户名  
  49. String userName=principals.getPrimaryPrincipal().toString();  
  50. //获取角色  
  51. Set<String> roleList=userMapper.queryRoleByName(userName);  
  52. //获取权限  
  53. Set<String> permsList=userMapper.queryPermsByName(userName);  
  54. SimpleAuthorizationInfo sa=new SimpleAuthorizationInfo();  
  55. sa.setRoles(roleList);  
  56. sa.setStringPermissions(permsList);  
  57. return sa;  
  58. }  
  59. }  
  60.    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot项目中使用Shiro进行安全控制,需要进行以下几个步骤。 1. 引入ShiroSpring Boot相关依赖 在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.6.0</version> </dependency> ``` 2. 配置Shiro的安全管理器 在Spring Boot的配置文件中,添加Shiro的相关配置: ```yaml # Shiro配置 shiro: # 配置安全管理器 securityManager: # 配置Realm realms: - name: myRealm # 配置自定义的Realm实现类 customRealm: com.example.demo.shiro.MyRealm # 配置Session管理器 sessionManager: # Session过期时间,单位:毫秒 globalSessionTimeout: 1800000 # 配置Cookie cookie: # Cookie名称 name: SHIROSESSIONID # Cookie过期时间,单位:秒 maxAge: 1800 # Cookie路径 path: / # 配置Shiro Filter filters: # 配置自定义的Filter实现类 myFilter: com.example.demo.shiro.MyFilter # 配置Filter Chain filterChainDefinitions: # 配置访问控制规则 /login: anon /logout: logout /**: myFilter ``` 其中,配置了安全管理器`securityManager`,包括了自定义的Realm实现类`MyRealm`、Session管理器和Cookie。 配置Shiro Filter`myFilter`,以及Filter Chain,其中`/login`可以匿名访问,`/logout`需要进行登出操作,其他URL需要经过自定义的Filter`MyFilter`进行访问控制。 3. 实现自定义Realm 在`MyRealm`类中,需要实现Shiro的`Realm`接口,重写`doGetAuthenticationInfo`和`doGetAuthorizationInfo`方法,完成身份认证和授权。 ```java public class MyRealm extends AuthorizingRealm { /** * 身份认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 获取用户名和密码 String username = (String) authenticationToken.getPrincipal(); String password = new String((char[]) authenticationToken.getCredentials()); // 根据用户名查询用户信息 User user = userService.findByUsername(username); // 判断用户是否存在 if (user == null) { throw new UnknownAccountException("用户不存在"); } // 判断密码是否正确 if (!password.equals(user.getPassword())) { throw new IncorrectCredentialsException("密码错误"); } // 将用户信息封装到AuthenticationInfo中 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, password, getName()); return authenticationInfo; } /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 获取用户信息 User user = (User) principalCollection.getPrimaryPrincipal(); // 查询用户角色和权限信息 List<Role> roles = roleService.findByUserId(user.getId()); List<Permission> permissions = permissionService.findByUserId(user.getId()); // 封装角色和权限信息到AuthorizationInfo中 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); for (Role role : roles) { authorizationInfo.addRole(role.getName()); } for (Permission permission : permissions) { authorizationInfo.addStringPermission(permission.getName()); } return authorizationInfo; } } ``` 4. 实现自定义Filter 在`MyFilter`类中,需要继承Shiro的`AccessControlFilter`类,重写`isAccessAllowed`和`onAccessDenied`方法,完成访问控制逻辑。 ```java public class MyFilter extends AccessControlFilter { @Override protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { // 获取Shiro的Subject对象 Subject subject = getSubject(servletRequest, servletResponse); // 判断是否已经登录 if (subject.isAuthenticated()) { return true; } // 判断是否是登录请求 HttpServletRequest request = (HttpServletRequest) servletRequest; if ("/login".equals(request.getServletPath())) { return true; } // 其他情况都要进行跳转到登录页面 redirectToLogin(servletRequest, servletResponse); return false; } @Override protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception { // 如果是Ajax请求,则返回JSON格式的数据 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; if (request.getHeader("X-Requested-With") != null && request.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest")) { response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(Result.fail("未登录或登录超时"))); } else { // 否则进行跳转到登录页面 redirectToLogin(servletRequest, servletResponse); } return false; } } ``` 5. 配置Shiro的注解支持 在Spring Boot的配置类中,添加`@EnableAspectJAutoProxy(proxyTargetClass = true)`注解和`@EnableAuthorization`注解,启用Shiro的注解支持和AOP功能。 ```java @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @EnableAuthorization public class ShiroConfig { // ... } ``` 至此,基于Shiro的安全控制已经配置完成。在需要进行访问控制的Controller方法上,添加相应的注解即可完成授权操作,例如`@RequiresPermissions("user:view")`表示需要拥有`user:view`权限才能访问该方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值