ApplicationCode:应用代码,程序员自己编写
Subject:shiro框架提供接口,代表当前“用户”,subject对象有状态;理解:subject包含自定义User对象
Shiro SecurityManager:核心,安全管理器;管理所有用户
Realm:框架提供一些,一般自己编写。通过realm调用dao查询安全数据(用户名密码;用户的权限,角色)
开始认证(登陆)
完善userAction中登陆:applicationCode --->Subject----->securityManager------->自定义realm
完善realm中认证方法:
基于shiro的url拦截方式权限控制
在realm中授权
applicationContext.xml
<!-- 配置shiro 过滤器工厂对象 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 注入安全管理器 --> <property name="securityManager" ref="securityManager"></property> <!-- private String loginUrl; 当后边配置url,需要当前用户认证通过后才可以访问;如果用户没有登陆,跳转登陆页面 private String successUrl; 权限不足页面 private String unauthorizedUrl; --> <property name="loginUrl" value="/login.jsp"></property> <property name="unauthorizedUrl" value="/unauthorized.jsp"></property> <!-- 注入过滤器链:配置系统中url请求拦截规则 注意:配置url拦截规则有顺序 authc:过滤器工厂产生过滤器之一 /**:所有请求 当系统发送某url要求当前用户必须认证通过后才能访问 anon:匿名过滤器:访问url不需要当前用户认证,没有权限可以访问 perms:权限过滤器:访问url需要当前用户具有某个权限才可以访问 --> <property name="filterChainDefinitions"> <value> /login.jsp = anon /css/** = anon /js/** = anon /images/** = anon /validatecode.jsp* = anon /userAction_login.action = anon /pages/base/standard.jsp = perms["standard_page"] /** = authc </value> </property> </bean> <!-- 配置安全管理器对象 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="bosRealm"></property> </bean> <!-- 配置realm对象 --> <bean id="bosRealm" class="com.itheima.bos.realm.BosRealm"></bean> <!-- spring提供配置shiro注解扫描 在servie层方法上使用shiro注解,运行时期此方法所在类产生代理对象 AutoProxy:自动代理,根据请求自动选择代理技术 jdk动态代理:基于接口 cglib动态代理:基于Class 注意:强制使用cglib动态代理 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> <property name="proxyTargetClass" value="true"></property> </bean> <!-- 配置shiro的切面:(切点+通知/增强) 增强:验证当前用户是否有权限 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>
public class UserAction extends BaseAction<User> { @Autowired private UserService userService; //接收验证码 private String checkCode; public void setCheckCode(String checkCode) { this.checkCode = checkCode; } /** * @Description: 基于shiro实现登陆(认证) * @return * @throws Exception * */ @Action("userAction_login") public String login() throws Exception { if(StringUtils.isNotBlank(model.getUsername())&& StringUtils.isNoneBlank(model.getPassword())&&StringUtils.isNotBlank(checkCode)){ //判断验证码 String realCheckCode = (String) ServletActionContext.getRequest().getSession().getAttribute("key"); if(checkCode.equals(realCheckCode)){ //相等,开始通过shiro实现认证 //通过工具类获取subject对象 Subject subject = SecurityUtils.getSubject(); //当前“用户”,未认证状态 //创建认证令牌; 封装页面提交用户名,密码 AuthenticationToken token = new UsernamePasswordToken(model.getUsername(), Md5Util.encode(model.getPassword()));; //logion方法调用安全管理器; try { subject.login(token); } catch (Exception e) { e.printStackTrace(); //认证失败 return "login"; } //认证通过 //从主角中获取用户信息,将用户的信息存Session中 User user = (User) subject.getPrincipal(); ServletActionContext.getRequest().getSession().setAttribute("loginUser", user); return "index"; } }else{ return "login"; } return super.execute(); } }
public class BosRealm extends AuthorizingRealm{ @Autowired private UserDao userDao; /** * @Description: * @param token subject.login方法中传 用户名密码令牌 * @return */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("开始认证"); UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; //页面输入的用户名 //根据用户名查询数据库中真实密码 String username = usernamePasswordToken.getUsername(); User user = userDao.findByUsername(username); if(user==null){ //用户名输出错误 return null; //当此方法中返回null,shiro会抛出异常 :未知账户异常 } //比对密码工作交给shiro框架 //p1:主角 p2:令牌/真实密码 p3:当前realm名称 AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName()); return info; } //授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("开始授权"); //TODO 后期改造查询数据库中对应的权限,角色 //返回简单授权信息:包含当前用户有的权限点;角色 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //添加用户权限 info.addStringPermission("standard_page"); info.addStringPermission("courier_delete"); //添加用户角色 info.addRole("admin"); return info; } }