发表于: 2017-12-22 21:57:08
1 578
今天完成的事:
今天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的功能东西还有点多。师兄用过他的缓存没把授权弄清楚就放一放了。
评论