发表于: 2017-12-22 21:57:08

1 577


今天完成的事:

        今天shiro和spring结合

shiro在web.xml的过滤器设置

<!-- shiro 安全过滤器 -->
<!-- The filter-name matches name of a 'shiroFilter' bean inside applicationContext.xml -->
<filter>
   <filter-name>shiroFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   <async-supported>true</async-supported>
   <init-param>
       <param-name>targetFilterLifecycle</param-name>
       <param-value>true</param-value>
   </init-param>
</filter>

<!-- Make sure any request you want accessible to Shiro is filtered. /* catches all -->
<!-- requests.  Usually this filter mapping is defined first (before all others) to -->
<!-- ensure that Shiro works in subsequent filters in the filter chain:             -->
<filter-mapping>
   <filter-name>shiroFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

spring-shiro.xml

<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
   <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>

<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
     class="com.github.zhangkaitao.shiro.chapter12.credentials.RetryLimitHashedCredentialsMatcher">
   <constructor-arg ref="cacheManager"/>
   <!-- 设置该密码匹配器使用的算法是 md5 -->
   <property name="hashAlgorithmName" value="md5"/>
   <property name="hashIterations" value="2"/>
   <property name="storedCredentialsHexEncoded" value="true"/>
</bean>

<!-- Realm实现 -->
<bean id="userRealm" class="com.github.zhangkaitao.shiro.chapter12.realm.UserRealm">
   <!--<property name="userService" ref="userService"/>-->
   <!-- 将上面声明的密码匹配器注入到自定义 Realm 的属性中去 -->
   <property name="credentialsMatcher" ref="credentialsMatcher"/>
   <!-- 启用缓存 -->
   <property name="cachingEnabled" value="true"/>
   <!-- 开启认证缓存-->
   <property name="authenticationCachingEnabled" value="true"/>
   <!-- 指定认证缓存的名字(与 ehcache.xml 中声明的相同) -->
   <property name="authenticationCacheName" value="authenticationCache"/>
   <!--开启授权缓存-->
   <property name="authorizationCachingEnabled" value="true"/>
   <!-- 指定授权缓存的名字(与 ehcache.xml 中声明的相同) -->
   <property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<!-- Shiro的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
   <!-- 权限管理器 -->
   <property name="securityManager" ref="securityManager"/>
   <!-- 登录地址 -->
   <property name="loginUrl" value="/login.jsp"/>
   <!-- 登录后跳转到业务页面 -->
   <property name="successUrl" value="/success.jsp"/>
   <!-- 错误页面 -->
   <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
   <!-- 权限配置 -->
   <!--<property name="filters">-->
       <!--<util:map>-->
           <!--<entry key="authc" value-ref="formAuthenticationFilter"/>-->
       <!--</util:map>-->
   <!--</property>-->
   <property name="filterChainDefinitions">
       <value>
           <!-- anon无权限访问请求 -->
           /index.jsp = anon
           /unauthorized.jsp = anon
           <!--/login.jsp = authc-->
           /logout = logout
           /test** = roles[admin]
           <!-- 需要权限为add的用户才能访问此请求-->
           <!--/user=perms[user:add]-->
           <!-- 需要管理员角色才能访问此页面 -->
           <!--/user/add=roles[admin]-->
           <!--拦截非静态资源的所有请求-->
           <!--/** = authc-->
           <!--/** = user-->
       </value>
   </property>
</bean>

<!-- Shiro生命周期处理器-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

登陆controller

 @RequestMapping(value = "/login", method = RequestMethod.POST)
public String doLogin(HttpServletRequest request, Model model) {
String msg = "";
       String userName = request.getParameter("username");
       String password = request.getParameter("password");
       System.out.println(userName);
       System.out.println(password);
//        封装
       UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
//        token.setRememberMe(true);
       Subject subject = SecurityUtils.getSubject();
       try {
subject.login(token);
//            判断用户是否已经登陆
           if (subject.isAuthenticated()) {
return "redirect:/success.jsp";
           } else {
return "login";
           }
} catch (IncorrectCredentialsException e) {
msg = "登录密码错误. Password for account " + token.getPrincipal() + " was incorrect.";
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (ExcessiveAttemptsException e) {
msg = "登录失败次数过多";
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (LockedAccountException e) {
msg = "帐号已被锁定. The account for username " + token.getPrincipal() + " was locked.";
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (DisabledAccountException e) {
msg = "帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled.";
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (ExpiredCredentialsException e) {
msg = "帐号已过期. the account for username " + token.getPrincipal() + "  was expired.";
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (UnknownAccountException e) {
msg = "帐号不存在. There is no user with username of " + token.getPrincipal();
           model.addAttribute("message", msg);
           System.out.println(msg);
       } catch (UnauthorizedException e) {
msg = "您没有得到相应的授权!" + e.getMessage();
           model.addAttribute("message", msg);
           System.out.println(msg);
       }
return "login";
   }

realm中进行密码匹配

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 把token转换成User对象
   String username = (String)token.getPrincipal();
   User user = userService.findByUsername(username);
   // 验证用户是否可以登录
   if(user == null) {
throw new UnknownAccountException();//没找到帐号
   }

if(Boolean.TRUE.equals(user.getLocked())) {
throw new LockedAccountException(); //帐号锁定
   }

//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
   SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), //用户名
           user.getPassword(), //密码
           ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt
           getName() //realm name
   );
   return authenticationInfo;
}

返回错误

登陆成功,角色并具有admin权限

shiro自带的密码加密加盐存放数据库

public void encryptPassword(User user) {

user.setSalt(randomNumberGenerator.nextBytes().toHex());

   String newPassword = new SimpleHash(
           algorithmName,
           user.getPassword(),
           ByteSource.Util.bytes(user.getCredentialsSalt()),
           hashIterations).toHex();

   user.setPassword(newPassword);
}


明天计划的事:

       加入mybatis,多表查询,授权

问题:

收获:

       shiro的功能东西还有点多。师兄用过他的缓存没把授权弄清楚就放一放了。


返回列表 返回列表
评论

    分享到