基于shiro框架进行认证(登录)操作
1.在pom.xml中引入shiro坐标
2.在web.xml中整合shiro过滤器
放在struts过滤器之前
</welcome-file-list>
<!-- spring整合shiro的过滤器-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.在spring容器中配置一个bean,id和过滤器name相同
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器对象 -->
<property name="securityManager" ref="securityManager"/>
<!--
private String loginUrl;
private String successUrl;
private String unauthorizedUrl;
-->
<property name="loginUrl" value="/login.jsp"/><!-- 登陆失败,跳转页面 -->
<property name="successUrl" value="/index.jsp"/><!-- 登陆成功,跳转页面 -->
<property name="unauthorizedUrl" value="/unauthorizedUrl.jsp"></property><!-- 授权不足,跳转页面 -->
<!-- 第一种权限控制方式:url拦截实现权限控制 -->
<property name="filterChainDefinitions"><!-- 配置权限过滤器规则 ,校验权限,什么样的请求应用什么样的权限 -->
<!--
authc:代表shiro框架提供的一个过滤器,作用是用于检查当前用户是否已经完成登录(认证)
如果已经完成登录,就放行,如果没有完成登录,跳转到登录页面
anon:代表框架提供的一个过滤器,作用是可以匿名(未登录)访问
-->
<value>
/login.jsp = anon
/js/** = anon
/css/** = anon
/images/** = anon
/validatecode.jsp* = anon
/userAction_login.action = anon
/** = authc
</value>
</property>
</bean>
<!-- 注册安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--将Realm注入到 安全管理器-->
<property name="realm" ref="bosUserLoginRealm"></property>
</bean>
<!--realm -->
<bean id="bosUserLoginRealm" class="cn.itcast.bos.realm.BosUserLoginRealm"></bean>
4.配置安全管理器
shiro框架调用流程
Application:应用代码,自己写的代码
Subject : shiro当中核心对象,当前系统用户对象
Shiro SecurityManager:安全管理器(最核心组件,管理其他组件)
Realm:安全管理器访问数据库 ,必须提供 Realm类
登陆案例
action
@Action(value="userAction_login",results={@Result(name="success",location="/index.jsp"),
@Result(name="failure",location="/login.jsp")})
public String login(){
//判断验证码是否输入且正确
String checkcodeS = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
if(StringUtils.isNotBlank(checkcode)&&checkcodeS.equals(checkcode)){
//正确,使用shior认证账号密码
//获取subject对象
Subject subject = SecurityUtils.getSubject();
//使用subject认证方法,进行认证
AuthenticationToken token=new UsernamePasswordToken(model.getUsername(), MD5Utils.md5(model.getPassword()));
try {
subject.login(token);//调用安全管理器
//登陆成功,跳转首页
return "success";
} catch (AuthenticationException e) {
// 登陆失败
ServletActionContext.getRequest().getSession().setAttribute("up", "账号或者密码错误");
e.printStackTrace();
return "failure";
}
获取到subject对象 ,调用安全管理器 ,进行校验,安全管理器最终调用Realm操作数据库
创建Realm
public class BosUserLoginRealm extends AuthorizingRealm {
@Autowired
private IUserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
/*
* 认证
* (non-Javadoc)
* @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 安全管理器调用 Realm持久层验证查询
UsernamePasswordToken upt=(UsernamePasswordToken)authenticationToken;
String username = upt.getUsername();
//根据用令牌中用户名查询客户对象
User user=userService.findByUsername(username);
if(null!=user){
//如果查询客户不为空 ,将用户信息和密码封装到AuthenticationInfo(返回它的实现类),返回给安全管理器
//安全管理器会自动校验密码,密码正确,代码正常执行,错误,抛出异常。
//参数一 可以放任意类型对象,一般放用户对象,该参数可以在任何位置获取到
//参数二 放查询出的密码
//参数三 Realm名称
//返回对象接口实现类
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
}
return null;
}
}
将Realm注入安全管理器调用查询
<!-- 注册安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--将Realm注入到 安全管理器-->
<property name="realm" ref="bosUserLoginRealm"></property>
</bean>
<!--realm -->
<bean id="bosUserLoginRealm" class="cn.huitong.bos.realm.BosUserLoginRealm"></bean>