软件152 尹以操

  springboot不像springmvc,它没有xml配置文件,那该如何配置shiro呢,其实也不难,用java代码+注解来解决这个问题。仅以此篇记录我对shiro的学习,如有对过客造成不便,实在抱歉!

  一、加入jar包

  既然要用到shiro,当然要加入它的jar包咯,在pom.xml中jar包依赖中加入:

  1. <dependency>

  2. <groupId>org.apache.shiro</groupId>

  3. <artifactId>shiro-spring</artifactId>

  4. <version>1.2.2</version>

  5. </dependency>

  二、写实体类

  这需要三个实体类,hibernate自动生成5个表

  User实体(用户):

  1. package com.cy.coo.bean;
  2.  
  3. import java.util.List;


  4. import javax.persistence.Column;


  5. import javax.persistence.Entity;


  6. import javax.persistence.FetchType;


  7. import javax.persistence.GeneratedValue;


  8. import javax.persistence.Id;


  9. import javax.persistence.JoinColumn;


  10. import javax.persistence.JoinTable;


  11. import javax.persistence.ManyToMany;
  12.  
  13. import com.fasterxml.jackson.annotation.JsonBackReference;
  14.  
  15. @Entity


  16. public class User {
  17. @Id</br>
  18. @GeneratedValue</br>
  19. </span><span style="color: #0000ff">private</span> Integer user_id;<span style="color: #008000">//</span><span style="color: #008000">用户序号</span></br>
  20.  
  21. @Column(unique=true)

  22. private String name;//账户



  23. private String password;//密码

  24. <span style="color: #0000ff">private</span> String salt;<span style="color: #008000">//</span><span style="color: #008000">盐</span></br></br>
  25. <span style="color: #0000ff">private</span> Integer state;<span style="color: #008000">//</span><span style="color: #008000">用户状态</span></br></br>
  26. <span style="color: #0000ff">private</span> String createtime;<span style="color: #008000">//</span><span style="color: #008000">创建时间</span></br></br>
  27.  
  28. @ManyToMany(fetch=FetchType.EAGER)//立即从数据库中进行加载数据;

  29. @JoinTable(name="User_Role",joinColumns={@JoinColumn(name="user_id")},

  30. inverseJoinColumns={@JoinColumn(name="role_id")})

  31. private List<Role> roleList;

  32. @JsonBackReference
  33. </span><span style="color: #0000ff">public</span> List&lt;Role&gt;<span style="color: #000000"> getRoleList(){</br>
  34.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> roleList;</br>
  35. }</br>
  36. </br>
  37. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setRoleList(List&lt;Role&gt;<span style="color: #000000"> roleList){</br>
  38.     </span><span style="color: #0000ff">this</span>.roleList=<span style="color: #000000">roleList;</br>
  39. }</br>
  40.  
  41. 注:其它gettersetter省略</span><span style="color: #000000">
  42.  
  43. }

  关于为什么要在getRolelist这个方法上加上@JsonBackReference注解,可以查看这篇文章http://blog.csdn.net/maxu12345/article/details/45538157

  Role实体(角色):

  1. package com.cy.coo.bean;

  2.  
  3. import java.io.Serializable;


  4. import java.util.ArrayList;


  5. import java.util.List;

  6.  
  7. import javax.persistence.Entity;


  8. import javax.persistence.FetchType;


  9. import javax.persistence.GeneratedValue;


  10. import javax.persistence.Id;


  11. import javax.persistence.JoinColumn;


  12. import javax.persistence.JoinTable;


  13. import javax.persistence.ManyToMany;

  14.  
  15. import com.fasterxml.jackson.annotation.JsonBackReference;

  16.  
  17. @Entity


  18. public class Role implements Serializable {


  19. private static final long serialVersionUID = 1L;

  20. @Id</br>
  21. @GeneratedValue</br>
  22. </span><span style="color: #0000ff">private</span> Integer role_id;<span style="color: #008000">//</span><span style="color: #008000">角色序号</span></br></br>
  23. <span style="color: #0000ff">private</span> String role_name;<span style="color: #008000">//</span><span style="color: #008000">角色名称</span></br></br>
  24. <span style="color: #0000ff">private</span> String role_description;<span style="color: #008000">//</span><span style="color: #008000">角色描述</span></br></br>
  25.  
  26. @ManyToMany

  27. @JoinTable(name = "User_Role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {

  28. @JoinColumn(name = "user_id") })

  29. private List<User> userList=new ArrayList<>();

  30. @ManyToMany<span style="color: #ff0000">(fetch</span></span><span style="color: #ff0000">=</span><span style="color: #000000"><span style="color: #ff0000">FetchType.EAGER)</span></br>
  31. @JoinTable(name</span>="Role_Function",joinColumns={@JoinColumn(name="role_id")},inverseJoinColumns=<span style="color: #000000">{</br>
  32.         @JoinColumn(name</span>="function_id"<span style="color: #000000">)})</br>
  33. </span><span style="color: #0000ff">private</span> List&lt;Function&gt; functionList=<span style="color: #0000ff">new</span> ArrayList&lt;&gt;<span style="color: #000000">();</br></br>
  34. @JsonBackReference</br>
  35. </span><span style="color: #0000ff">public</span> List&lt;Function&gt;<span style="color: #000000"> getFunctionList(){</br>
  36.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> functionList;</br>
  37. }</br>
  38. </br>
  39. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setFunctionList(List&lt;Function&gt;<span style="color: #000000"> functionList){</br>
  40.     </span><span style="color: #0000ff">this</span>.functionList=<span style="color: #000000">functionList;</br>
  41. }</br>
  42. @JsonBackReference</br>
  43. </span><span style="color: #0000ff">public</span> List&lt;User&gt;<span style="color: #000000"> getUserList() {</br>
  44.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> userList;</br>
  45. }</br></br>
  46. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setUserList(List&lt;User&gt;<span style="color: #000000"> userList) {</br>
  47.     </span><span style="color: #0000ff">this</span>.userList =<span style="color: #000000"> userList;</br>
  48. }</br></br>
  49. </span><span style="color: #0000ff">public</span><span style="color: #000000"> Integer getRole_id() {</br>
  50.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> role_id;</br>
  51. }</br></br>
  52. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> setRole_id(Integer role_id) {</br>
  53.     </span><span style="color: #0000ff">this</span>.role_id =<span style="color: #000000"> role_id;</br>
  54. }</br></br></br>
  55. </span><span style="color: #0000ff">public</span><span style="color: #000000"> String getRole_name() {</br>
  56.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> role_name;</br>
  57. }</br></br>
  58. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> setRole_name(String role_name) {</br>
  59.     </span><span style="color: #0000ff">this</span>.role_name =<span style="color: #000000"> role_name;</br>
  60. }</br>
  61. </span><span style="color: #0000ff">public</span><span style="color: #000000"> String getRole_description() {</br>
  62.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> role_description;</br>
  63. }</br>
  64. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> setRole_description(String role_description) {</br>
  65.     </span><span style="color: #0000ff">this</span>.role_description =<span style="color: #000000"> role_description;</br>
  66. }</br>
  67.  
  68. }

  Function实体(权限):

  1. package com.cy.coo.bean;

  2.  
  3. import java.util.List;

  4.  
  5. import javax.persistence.Entity;


  6. import javax.persistence.GeneratedValue;


  7. import javax.persistence.Id;


  8. import javax.persistence.JoinColumn;


  9. import javax.persistence.JoinTable;


  10. import javax.persistence.ManyToMany;

  11.  
  12. @Entity


  13. public class Function {





  14. @Id


  15. @GeneratedValue


  16. private Integer function_id;//功能序号

  17. <span style="color: #0000ff">private</span> String permission;<span style="color: #008000">//</span><span style="color: #008000">权限字符串</span></br>
  18.  


  19. @ManyToMany</br>
  20. @JoinTable(name </span>= "Role_Function", joinColumns = { @JoinColumn(name = "function_id") }, inverseJoinColumns =<span style="color: #000000"> {</br>
  21.         @JoinColumn(name </span>= "role_id"<span style="color: #000000">) })</br>
  22. </span><span style="color: #0000ff">private</span> List&lt;Role&gt;<span style="color: #000000"> roleList;</br></br>
  23. </span><span style="color: #0000ff">public</span> List&lt;Role&gt;<span style="color: #000000"> getRoleList() {</br>
  24.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> roleList;</br>
  25. }</br>
  26. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setRoleList(List&lt;Role&gt;<span style="color: #000000"> roleList) {</br>
  27.     </span><span style="color: #0000ff">this</span>.roleList =<span style="color: #000000"> roleList;</br>
  28. }</br>
  29. </span><span style="color: #0000ff">public</span><span style="color: #000000"> Integer getFunction_id() {</br>
  30.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> function_id;</br>
  31. }</br>
  32. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> setFunction_id(Integer function_id) {</br>
  33.     </span><span style="color: #0000ff">this</span>.function_id =<span style="color: #000000"> function_id;</br>
  34. }</br></br></br>
  35. </span><span style="color: #0000ff">public</span><span style="color: #000000"> String getPermission() {</br>
  36.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> permission;</br>
  37. }</br></br>
  38. </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> setPermission(String permission) {</br>
  39.     </span><span style="color: #0000ff">this</span>.permission =<span style="color: #000000"> permission;</br>
  40. }</br>
  41.  
  42. }

  这几个实体类的具体关系如下图,也完美的解释了为什么会生成5张表:

  三、写一个与前端交互的controller方法,service层的具体逻辑的方法

  1. @PostMapping(value = "/logon")

  2. public Object logon(@RequestBody Login user) {

  3.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> userService.login(user);</br>
  4. }</span></pre>
  5.  

  这个方法就是将前端传来的username和password封装到Login类中,Login类也只有这两个属性,然后调用Service层的login方法来处理。下面是service的login方法:

  1. /**

  2. * 用户登录 create by yyc 2017年5月12日下午4:31:26

  3. */

  4. @Override

  5. public Object login(Login user) {

  6. String username = user.getUsername().trim();

  7. String password = user.getPassword().trim();

  8.     </span><span style="color: #008000">//</span><span style="color: #008000"> 检查空值</span></br>
  9.     <span style="color: #0000ff">if</span> (!<span style="color: #000000">CheckObjectField.CheckField(user)) {</br>
  10.         </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ResultException(CheckObjectField.FieldName + "为空!"<span style="color: #000000">);
  11.     }</br></br></br>
  12.     </span><span style="color: #008000">//</span><span style="color: #008000"> 检查用户状态</span></br>
  13.     Integer userState =<span style="color: #000000"> userRepository.findUserState(username);</br>
  14.     </span><span style="color: #0000ff">if</span> (<span style="color: #0000ff">new</span> Integer("1"<span style="color: #000000">).equals(userState)) {</br>
  15.         </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ResultException("该用户已锁定"<span style="color: #000000">);</br>
  16.     }</br></br>
  17.     </span><span style="color: #008000">//</span><span style="color: #008000"> 1、获取Subject实例对象</span></br>
  18.     Subject currentUser =<span style="color: #000000"> SecurityUtils.getSubject();</br></br>
  19.     </span><span style="color: #008000">//</span><span style="color: #008000"> 2、判断当前用户是否登录</span></br>
  20.     <span style="color: #0000ff">if</span> (currentUser.isAuthenticated() == <span style="color: #0000ff">false</span><span style="color: #000000">) {</br>
  21.         </span><span style="color: #008000">//</span><span style="color: #008000"> 3、将用户名和密码封装到UsernamePasswordToken</span></br>
  22.         UsernamePasswordToken token = <span style="color: #0000ff">new</span><span style="color: #000000"> UsernamePasswordToken(username, password);</br></br>
  23.         </span><span style="color: #008000">//</span><span style="color: #008000"> 4、认证</span></br>
  24.         <span style="color: #0000ff">try</span><span style="color: #000000"> {</br>
  25.             currentUser.login(token);</span><span style="color: #008000">//</span><span style="color: #008000"> 传到MyAuthorizingRealm类中的方法进行认证</span>
  26.             Session session =<span style="color: #000000"> currentUser.getSession();</br>
  27.             session.setAttribute(</span>"username"<span style="color: #000000">, username);</br>
  28.         } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (AuthenticationException e) {</br>
  29.             </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ResultException("密码或用户名错误"<span style="color: #000000">);</br>
  30.         }</br>
  31.     }</br>
  32.     </span><span style="color: #008000">//</span><span style="color: #008000"> 根据用户名查询角色信息</span></br>
  33.     List&lt;String&gt; RoleNames =<span style="color: #000000"> roleService.findRoleName(username);</br></br>
  34.     </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span><span style="color: #000000"> LoginReturn(username, RoleNames);</br>
  35. }</span></pre>
  36.  

  service中主要是将用户名和密码封装到shiro的UsernamePasswordToken中,然后将token对象放到SecurityUtils.getSubject()的login方法中,以便shiro认证登录使用。认证失败就会抛出AuthenticationException这个异常,就对异常进行相应的操作,这里的处理是抛出一个自定义异常ResultException。

  四、写我认为的shiro的核心类

  1. package com.cy.coo.shiro;
  2.  
  3. import org.apache.shiro.authc.AuthenticationException;


  4. import org.apache.shiro.authc.AuthenticationInfo;


  5. import org.apache.shiro.authc.AuthenticationToken;


  6. import org.apache.shiro.authc.SimpleAuthenticationInfo;


  7. import org.apache.shiro.authc.UsernamePasswordToken;


  8. import org.apache.shiro.authz.AuthorizationInfo;


  9. import org.apache.shiro.authz.SimpleAuthorizationInfo;


  10. import org.apache.shiro.realm.AuthorizingRealm;


  11. import org.apache.shiro.subject.PrincipalCollection;


  12. import org.apache.shiro.util.ByteSource;


  13. import org.slf4j.Logger;


  14. import org.slf4j.LoggerFactory;


  15. import org.springframework.beans.factory.annotation.Autowired;

  16.  
  17. import com.cy.coo.bean.Function;


  18. import com.cy.coo.bean.Role;


  19. import com.cy.coo.bean.User;


  20. import com.cy.coo.service.UserService;

  21.  
  22. /**

  23. *

  24. *
    • @author E-mail:34782655@qq.com
    • @version 创建时间:2017年5月8日 上午10:50:50
    • 类说明:
    • --

    • */

    • public class MyAuthorizingRealm extends AuthorizingRealm {
  25. </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">final</span> <span style="color: #0000ff">static</span> Logger logger=LoggerFactory.getLogger(MyAuthorizingRealm.<span style="color: #0000ff">class</span><span style="color: #000000">);
  26. @Autowired
  27. </span><span style="color: #0000ff">private</span><span style="color: #000000"> UserService userService;</br>
  28. </span><span style="color: #008000">//</span><span style="color: #008000">shiro的权限配置方法</span></br>
  29.  
  30. @Override


  31. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

  32.     logger.info(</span>"权限配置--&gt;doGetAuthorizationInfo"<span style="color: #000000">);</br></br>
  33.     SimpleAuthorizationInfo authorizationInfo </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> SimpleAuthorizationInfo();</br>
  34.     logger.info(</span>"-----------------------------&gt;"+<span style="color: #000000">principals.getPrimaryPrincipal());</br>
  35.     User user</span>=<span style="color: #000000">(User) principals.getPrimaryPrincipal();</br>
  36.     </span><span style="color: #0000ff">for</span><span style="color: #000000">(Role role:user.getRoleList()){</br>
  37.         authorizationInfo.addRole(role.getRole_name());</br>
  38.         </span><span style="color: #0000ff">for</span><span style="color: #000000">(Function function:role.getFunctionList()){</br>
  39.             authorizationInfo.addStringPermission(function.getPermission());</br>
  40.         }</br>
  41.     }</br>
  42.     logger.info(</span>"用户"+user.getName()+"具有的角色:"+<span style="color: #000000">authorizationInfo.getRoles());</br>
  43.     logger.info(</span>"用户"+user.getName()+"具有的权限:"+<span style="color: #000000">authorizationInfo.getStringPermissions());</br></br>
  44.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> authorizationInfo;</br>
  45. }
  46.     </span><span style="color: #008000">//</span><span style="color: #008000">shiro的身份验证方法</span></br>
  47.  
  48. @Override


  49. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

  50.     logger.info(</span>"正在验证身份..."<span style="color: #000000">);</br>
  51.     SimpleAuthenticationInfo info</span>=<span style="color: #0000ff">null</span><span style="color: #000000">;</br></br>
  52.     </span><span style="color: #008000">//</span><span style="color: #008000">将token转换成UsernamePasswordToken</span></br>
  53.     UsernamePasswordToken upToken =<span style="color: #000000"> (UsernamePasswordToken) token;</br>
  54.     </span><span style="color: #008000">//</span><span style="color: #008000">从转换后的token中获取用户名</span></br>
  55.     String username=<span style="color: #000000"> upToken.getUsername();  </br>
  56.     logger.info(</span>"-----&gt;"+<span style="color: #000000">username);</br></br>
  57.     </span><span style="color: #008000">//</span><span style="color: #008000">查询数据库,得到用户</span></br>
  58.     User user=<span style="color: #000000">userService.findByName(username);</br>
  59.     </span><span style="color: #0000ff">if</span>(user==<span style="color: #0000ff">null</span><span style="color: #000000">){</br>
  60.         </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span><span style="color: #000000">;</br>
  61.     }</br>
  62.     </span><span style="color: #008000">//</span><span style="color: #008000">得到加密密码的盐值</span></br>
  63.     ByteSource salt =<span style="color: #000000"> ByteSource.Util.bytes(user.getSalt());</br>
  64.  
  65. // logger.info("加密密码的盐:"+salt);


  66. // //得到盐值加密后的密码:只用于方便数据库测试,后期不会用到。


  67. // Object md = new SimpleHash("MD5",upToken.getPassword(),salt,1024);


  68. // logger.info("盐值加密后的密码:"+md);




  69. info = new SimpleAuthenticationInfo(


  70. user, //用户名


  71. user.getPassword(), //密码


  72. salt, //加密的盐值


  73. getName() //realm name


  74. );


  75. return info;


  76. }

  77. }

  这个类继承shiro的AuthorizingRealm ,主要有两个方法,一个是权限配置,一个是身份认证,权限配置:当我们要用到权限时shiro会回调doGetAuthorizationInfo这个方法,对当前的用户分配权限,这个方法中的嵌套for循环是怎么回事呢,其实就是将数据库中的对应角色、权限放进shiro中,让他来管理,这需要实体类User中有getRoleList()、getRole_name()和getFunctionList()、getPermission这几个方法,这几个个方法就是设计数据库和实体类时的东西了,关于shiro权限相关的实体类在前面已经给出了。身份认证:在用户登录认证的时候回调,认证失败就抛出AuthenticationException。

  五、shiro配置类

  1. package com.cy.coo.shiro;
  2.  
  3. import java.util.LinkedHashMap;


  4. import java.util.Map;

  5.  
  6. import org.apache.shiro.authc.credential.HashedCredentialsMatcher;


  7. import org.apache.shiro.cache.ehcache.EhCacheManager;


  8. import org.apache.shiro.mgt.SecurityManager;


  9. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;


  10. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;


  11. import org.apache.shiro.web.mgt.CookieRememberMeManager;


  12. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;


  13. import org.apache.shiro.web.servlet.SimpleCookie;


  14. import org.slf4j.Logger;


  15. import org.slf4j.LoggerFactory;

  16. import org.springframework.beans.factory.annotation.Qualifier;


  17. import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;


  18. import org.springframework.context.annotation.Bean;


  19. import org.springframework.context.annotation.Configuration;


  20. import org.springframework.core.io.ClassPathResource;

  21.  
  22. @Configuration // 等价于beans


  23. public class ShiroConfig {

  24. </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> Logger log = LoggerFactory.getLogger(ShiroFilterFactoryBean.<span style="color: #0000ff">class</span><span style="color: #000000">);</br></br>
  25. @Bean(name </span>= "securityManager"<span style="color: #000000">)</br>
  26. </span><span style="color: #0000ff">public</span> SecurityManager securityManager(@Qualifier("authRealm"<span style="color: #000000">) MyAuthorizingRealm authRealm,</br>
  27.         @Qualifier(</span>"cookieRememberMeManager"<span style="color: #000000">) CookieRememberMeManager cookieRememberMeManager) {</br>
  28.     log.info(</span>"securityManager()"<span style="color: #000000">);</br>
  29.     DefaultWebSecurityManager securityManager </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> DefaultWebSecurityManager();</br>
  30.     </span><span style="color: #008000">//</span><span style="color: #008000"> 设置realm.</span></br>
  31.  
  32. securityManager.setRealm(authRealm);

  33.     </span><span style="color: #008000">//</span><span style="color: #008000"> 设置rememberMe管理器</span></br>
  34.  
  35. securityManager.setRememberMeManager(cookieRememberMeManager);

  36.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> securityManager;</br>
  37. }
  38. </span><span style="color: #008000">/**</span><span style="color: #008000"></br>
  39.  * realm</br>
  40.  *
  41.  * </span><span style="color: #808080">@return</span></br>
  42.  <span style="color: #008000">*/</span><span style="color: #000000"></br>
  43. @Bean(name </span>= "authRealm"<span style="color: #000000">)</br>
  44. </span><span style="color: #0000ff">public</span><span style="color: #000000"> MyAuthorizingRealm myAuthRealm(</br>
  45.         @Qualifier(</span>"hashedCredentialsMatcher"<span style="color: #000000">) HashedCredentialsMatcher matcher,</br>
  46.         @Qualifier(</span>"ehCacheManager"<span style="color: #000000">) EhCacheManager  ehCacheManager) {</br>
  47.     log.info(</span>"myShiroRealm()"<span style="color: #000000">);</br>
  48.     MyAuthorizingRealm myAuthorizingRealm </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> MyAuthorizingRealm();</br>
  49.     </span><span style="color: #008000">//</span><span style="color: #008000"> 设置密码凭证匹配器</span></br>
  50.     myAuthorizingRealm.setCredentialsMatcher(matcher); <span style="color: #008000">//</span><span style="color: #008000"> myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());</br>
  51.     </span><span style="color: #008000">//</span><span style="color: #008000"> 设置缓存管理器</span></br>
  52.  
  53. myAuthorizingRealm.setCacheManager(ehCacheManager);

  54.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> myAuthorizingRealm;</br>
  55. }</br>
  56.  
  57.     /**


  58. * 缓存管理器


  59. * @return

  60. */


  61. @Bean(value="ehCacheManager")


  62. public EhCacheManager ehCacheManager(@Qualifier("ehCacheManagerFactoryBean") EhCacheManagerFactoryBean bean) {


  63. log.info("ehCacheManager()");


  64. EhCacheManager cacheManager = new EhCacheManager();


  65. cacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");


  66. return cacheManager;


  67. }

  68. </span><span style="color: #008000">/**</span><span style="color: #008000"></br>
  69.  * cookie对象;</br>
  70.  * </br>
  71.  * </span><span style="color: #808080">@return</span></br>
  72.  <span style="color: #008000">*/</span><span style="color: #000000"></br>
  73. @Bean</br>
  74. </span><span style="color: #0000ff">public</span><span style="color: #000000"> SimpleCookie rememberMeCookie() {</br>
  75.     log.info(</span>"rememberMeCookie()"<span style="color: #000000">);</br>
  76.     </span><span style="color: #008000">//</span><span style="color: #008000"> 这个参数是cookie的名称,对应前端的checkbox 的name = rememberMe</span></br>
  77.     SimpleCookie simpleCookie = <span style="color: #0000ff">new</span> SimpleCookie("rememberMe"<span style="color: #000000">);</br>
  78.     </span><span style="color: #008000">//</span><span style="color: #008000"> &lt;!-- 记住我cookie生效时间30天(259200) ,单位秒;--&gt;</span></br>
  79.     simpleCookie.setMaxAge(259200<span style="color: #000000">);</br>
  80.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> simpleCookie;</br>
  81. }</br>
  82. </span><span style="color: #008000">/**</span><span style="color: #008000"></br>
  83.  * 记住我管理器 cookie管理对象;</br></br>
  84.  *
  85.  * </span><span style="color: #808080">@return</span></br>
  86.  <span style="color: #008000">*/</span><span style="color: #000000"></br>
  87. @Bean(name </span>= "cookieRememberMeManager"<span style="color: #000000">)</br>
  88. </span><span style="color: #0000ff">public</span><span style="color: #000000"> CookieRememberMeManager rememberMeManager() {</br>
  89.     System.out.println(</span>"rememberMeManager()"<span style="color: #000000">);</br>
  90.     CookieRememberMeManager cookieRememberMeManager </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> CookieRememberMeManager();</br>
  91.     cookieRememberMeManager.setCookie(rememberMeCookie());</br>
  92.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> cookieRememberMeManager;</br>
  93. }</br>
  94. </span><span style="color: #008000">/**</span><span style="color: #008000">
  95.  * 密码匹配凭证管理器
  96.  *
  97.  * </span><span style="color: #808080">@return</span></br>
  98.  <span style="color: #008000">*/</span><span style="color: #000000"></br>
  99. @Bean(name </span>= "hashedCredentialsMatcher"<span style="color: #000000">)</br>
  100. </span><span style="color: #0000ff">public</span><span style="color: #000000"> HashedCredentialsMatcher hashedCredentialsMatcher() {</br>
  101.     log.info(</span>"hashedCredentialsMatcher()"<span style="color: #000000">);</br>
  102.     HashedCredentialsMatcher hashedCredentialsMatcher </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> HashedCredentialsMatcher();</br></br>
  103.     hashedCredentialsMatcher.setHashAlgorithmName(</span>"MD5");<span style="color: #008000">//</span><span style="color: #008000"> 散列算法:这里使用MD5算法;</span></br>
  104.     hashedCredentialsMatcher.setHashIterations(1024);<span style="color: #008000">//</span><span style="color: #008000"> 散列的次数,比如散列两次,相当于</br>
  105.                                                         </span><span style="color: #008000">//</span><span style="color: #008000"> md5(md5(""));</span></br></br>
  106.     <span style="color: #0000ff">return</span><span style="color: #000000"> hashedCredentialsMatcher;</br>
  107. }</br>
  108. </span><span style="color: #008000">/**</span><span style="color: #008000"></br>
  109.  * 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持; Controller才能使用@RequiresPermissions</br></br>
  110.  *
  111.  * </span><span style="color: #808080">@param</span><span style="color: #008000"> securityManager</br>
  112.  * </span><span style="color: #808080">@return</span></br>
  113.  <span style="color: #008000">*/</span><span style="color: #000000"></br>
  114. @Bean</br>
  115. </span><span style="color: #0000ff">public</span><span style="color: #000000"> AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(</br>
  116.         @Qualifier(</span>"securityManager"<span style="color: #000000">) SecurityManager securityManager) {</br>
  117.     log.info(</span>"authorizationAttributeSourceAdvisor()"<span style="color: #000000">);</br>
  118.     AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> AuthorizationAttributeSourceAdvisor();</br>
  119.     authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);</br>
  120.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> authorizationAttributeSourceAdvisor;</br>
  121. }</br>
  122. @Bean</br>
  123. </span><span style="color: #0000ff">public</span> ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager"<span style="color: #000000">) SecurityManager securityManager) {</br>
  124.     log.info(</span>"shirFilter()"<span style="color: #000000">);</br>
  125.     ShiroFilterFactoryBean shiroFilterFactoryBean </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> ShiroFilterFactoryBean();</br></br>
  126.     </span><span style="color: #008000">//</span><span style="color: #008000"> 必须设置 SecurityManager</span></br>
  127.  
  128. shiroFilterFactoryBean.setSecurityManager(securityManager);

  129.     </span><span style="color: #008000">//</span><span style="color: #008000"> 拦截器.</span></br>
  130.     Map&lt;String, String&gt; map = <span style="color: #0000ff">new</span> LinkedHashMap&lt;String, String&gt;<span style="color: #000000">();</br></br>
  131.     map.put(</span>"/logout", "logout"<span style="color: #000000">);</br>
  132.     map.put(</span>"/login", "anon"<span style="color: #000000">);</br>
  133.     map.put(</span>"/logon", "anon"<span style="color: #000000">);</br></br>
  134.     map.put(</span>"/**", "authc"<span style="color: #000000">);</br></br>
  135.     </span><span style="color: #008000">//</span><span style="color: #008000"> 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面</span></br>
  136.     shiroFilterFactoryBean.setLoginUrl("/login"<span style="color: #000000">);</br>
  137.     </span><span style="color: #008000">//</span><span style="color: #008000"> 登录成功后要跳转的链接</span></br>
  138.     shiroFilterFactoryBean.setSuccessUrl("/index"<span style="color: #000000">);</br>
  139.     </span><span style="color: #008000">//</span><span style="color: #008000"> 未授权界面;</span></br>
  140.     shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"<span style="color: #000000">);</br></br>
  141.     shiroFilterFactoryBean.setFilterChainDefinitionMap(map);</br>
  142.     </span><span style="color: #0000ff">return</span><span style="color: #000000"> shiroFilterFactoryBean;</br>
  143. }</br>
  144.  
  145. }

  这个没什么好说的,最后一个类是shiro的过滤器配置。可以看到我在每个方法上面加了一个@Bean(name="..."),其实这是spring的注解,将这个类放到spring容器中管理,在方法形参中使用@Qualifier(...)来使用它,以致于我们在方法体中调用某个方法时就方面多了。

在这里,关于shiro在springboot中的基础配置就完成了。下面是期间遇到的错误解决方案:

错误一:关于实体类的错误,springboot 中hibernate懒加载  报错....................................No  Session
解决方法:新建类 配置OpenEntityManagerInViewFilter    以及  上面角色类(表)和用户类(表)(Role、User)Role的红色字体也是必须的,及@ManyToMany(fetch=FetchType.EAGER)
由于博主基础的局限还不知道具体的原因是什么,但是解决了就好。
  1. @Configuration
  2. public class HibernateConfig {

  3. @Bean

  4. public FilterRegistrationBean registerOpenEntityManagerInViewFilterBean() {

  5. FilterRegistrationBean registrationBean = new FilterRegistrationBean();

  6. OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();

  7. registrationBean.setFilter(filter);

  8. registrationBean.setOrder(5);

  9. return registrationBean;

  10. }

  11. }

参考文章:

http://stackoverflow.com/questions/33622222/spring-boot-opensessioninviewfilter-with-actuator-and-custom-security 

http://www.jianshu.com/p/a827ecdda99f

http://www.w_2bc.com/article/201653 /*这个链接博客园不让我发啊,把w_2_b_c中的下划线删了即可*/

错误二:这个在前面也提到过了,返回json数据出现Could not write JSON document: Infinite recursion(无法编写JSON文档:无限递归 );

在后面的使用中发现这个错误也是这样解决的,java.lang.IllegalStateException: Cannot call sendError() after the response has been committed,错误页面到最后就是这样,如图:

解决方法:

  在controller返回数据到统一json转换的时候,出现了json infinite recursion stackoverflowerror的错误,即json在将对象转换为json格式的数据的时候,出现了无限递归调用的情况。
具体的情况如下:
    A类中,有个属性:List<B> b, A与B的关系为 OneToMany;在B类中,有属性A a,引用到A中的字段id,并作为外键。hibernate查询结果正常,可以看到返回的A对象中,有b参数值,但在json转换的时候就出现了无限递归的情况。个人分析,应该是json在序列化A中的b属性的时候,找到了B类,然后序列化B类,而B类中有a属性,因此,为了序列化a属性,json又得去序列化A类,如此递归反复,造成该问题。
解决:
    在B类中a的getter setter方法上加注解@JsonBackReference,其实自己试过只在getter方法上加@JsonBackReference也够了。
 
 

原文地址:https://www.cnblogs.com/hyyq/p/6886004.html

  1. </div>

Springboot+shiro配置笔记+错误小结(转)的更多相关文章

  1. (转)Springboot+shiro配置笔记+错误小结

    springboot不像springmvc,它没有xml配置文件,那该如何配置shiro呢,其实也不难,用java代码+注解来解决这个问题.仅以此篇记录我对shiro的学习,如有对过客造成不便,实在抱 ...

  2. Springboot+shiro配置笔记+错误小结

    软件152 尹以操 springboot不像springmvc,它没有xml配置文件,那该如何配置shiro呢,其实也不难,用java代码+注解来解决这个问题.仅以此篇记录我对shiro的学习,如有对 ...

  3. springboot shiro配置

    导入相关包(这里配合使用Ehcache缓存) <dependency> <groupId>org.apache.shiro</groupId> <artifa ...

  4. SpringBoot整合Shiro 二:Shiro配置类

    环境搭建见上篇:SpringBoot整合Shiro 一:搭建环境 Shiro配置类配置 shiro的配置主要集中在 ShiroFilterFactoryBean 中 关于权限: anon:无需认证就可 ...

  5. springboot学习笔记:11.springboot+shiro+mysql+mybatis(通用mapper)+freemarker+ztree+layui实现通用的java后台管理系统(权限管理+用户管理+菜单管理)

    一.前言 经过前10篇文章,我们已经可以快速搭建一个springboot的web项目: 今天,我们在上一节基础上继续集成shiro框架,实现一个可以通用的后台管理系统:包括用户管理,角色管理,菜单管理 ...

  6. SpringBoot+Shiro学习(七):Filter过滤器管理

    SpringBoot+Shiro学习(七):Filter过滤器管理 Hiwayz 关注  0.5 2018.09.06 19:09* 字数 1070 阅读 5922评论 1喜欢 20 先从我们写的一个 ...

  7. Shiro学习笔记(5)——web集成

    Web集成 shiro配置文件shiroini 界面 webxml最关键 Servlet 測试 基于 Basic 的拦截器身份验证 Web集成 大多数情况.web项目都会集成spring.shiro在 ...

  8. springboot+shiro

    作者:纯洁的微笑 出处:http://www.ityouknow.com/ 这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公 ...

  9. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

随机推荐

  1. dreamweaver 8的替换功能

    dreamweaver 8的替换功能 下面教你用dreamweaver 8的替换功能来删除这些冗余代码. 查找范围:文件夹(然后选取你需要替换的文件夹) 搜索:源代码查找:\btppabs=" ...

  2. 【基础篇】DatePickerDialog日期控件的基本使用(一)

    项目步骤: 1.首先在Main.xml布局文件中添加一个Button标签,用来点击显示日期控件,Main.xml内容如下: <RelativeLayout xmlns:android=" ...

  3. SQL 金额添加千分位

    SELECT CONVERT(NVARCHAR(50),CAST(1000000 AS MONEY),1) SELECT CONVERT(NVARCHAR,CAST(1343432432434.8 A ...

  4. 韦东山ARM裸机笔记(2)--vi编辑器

    VI编辑器(Visual Interface--可视化接口) 一.Linux下的一个文本编辑器,所具备的基本功能: 打开.新建.保存文件 光标移动 文本编辑 (多行间 | 多列间)复制.粘贴.删除 查 ...

  5. POJ——T 3461 Oulipo

    http://poj.org/problem?id=3461 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42698   ...

  6. smarty模板引擎(一)基础知识

    一.基本概念 1.什么是mvc?     mvc是一种开发模式,核心思想是:数据的输入.数据的处理.数据显示的强制分离. 2.什么是smarty?     smarty是一个php的模板引擎.更明白的 ...

  7. 【吴节操点评】中国企业SaaS应用深谙未来者寥寥数几 两极分化将加剧

    数年前,在国外企业级应用如火如荼的时候.国内却是一片空白.而现在企业SaaS应用市场,包含用友.金蝶.东软在内的三巨头.已经有数十家之多.相比美国3000亿美元的企业应用三巨头来说,中国企业应用前三甲 ...

  8. 基于WebSphere与Domino的电子商务网站构架分析

    650) this.width=650;" border="0" alt="174812596.jpg" src="http://img1. ...

  9. [ Tomcat ] [ startup ] Tomcat 無法在時限內開啟問題

    http://www.ewdna.com/2011/12/tomcat-server-in-eclipse-unable-to.html

  10. 图片拖拽缩放功能:兼容Chrome、Firefox、IE8+

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...