ssm 整合 shiro 框架,对用户的登录操作进行认证和授权,目的很纯粹就是为了增加系统的安全线,至少不要输在门槛上嘛。
这几天在公司独立开发一个供公司内部人员使用的小管理系统,客户不多但是登录一直都是简单的校验查询,没有使用任何安全框架来保驾护航,下午终于拿出以前的手段来完善了一下,将 shiro 安全框架与 ssm 整合使用的步骤和大家分享一下,都是些简单易懂的东西,希望努力没有白费,帮到大家。
ssm 整合 shiro 安全框架的步骤:
1、引入 shiro 安全框架的所需 jar 包
- 1 <!-- shiro -->
- 2 <dependency>
- 3 <groupId>org.apache.shiro</groupId>
- 4 <artifactId>shiro-core</artifactId>
- 5 <version>1.2.3</version>
- 6 </dependency>
- 7 <dependency>
- 8 <groupId>org.apache.shiro</groupId>
- 9 <artifactId>shiro-spring</artifactId>
- 10 <version>1.2.3</version>
- 11 </dependency>
- 12 <dependency>
- 13 <groupId>org.apache.shiro</groupId>
- 14 <artifactId>shiro-web</artifactId>
- 15 <version>1.2.3</version>
- 16 </dependency>
- 17 <dependency>
- 18 <groupId>org.apache.shiro</groupId>
- 19 <artifactId>shiro-ehcache</artifactId>
- 20 <version>1.2.3</version>
- 21 </dependency>
2、在 web.xml 文件中配置 shiro 拦截器
- 1 <!-- spring整合安全框架 -->
- 2 <filter>
- 3 <filter-name>DelegatingFilterProxy</filter-name>
- 4 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- 5 <!-- 初始化参数 -->
- 6 <init-param>
- 7 <param-name>targetBeanName</param-name>
- 8 <param-value>shiroFilter</param-value>
- 9 </init-param>
- 10 </filter>
- 11 <filter-mapping>
- 12 <filter-name>DelegatingFilterProxy</filter-name>
- 13 <url-pattern>/*</url-pattern>
- 14 </filter-mapping>
3、创建 spring 整合 shiro 安全框架的配置文件 applicationContext-shiro.xml(各位在拷贝的时候记得修改一下跳转连接地址)
- 1 <!-- shiro开启事务注解 -->
- 2 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- 3 <property name="securityManager" ref="securityManager" />
- 4 </bean>
- 5
- 6 <!--
- 7 /** 除了已经设置的其他路径的认证
- 8 -->
- 9 <!-- shiro工厂bean配置 -->
- 10 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- 11 <!-- shiro的核心安全接口 -->
- 12 <property name="securityManager" ref="securityManager"></property>
- 13 <!-- 要求登录时的连接 -->
- 14 <property name="loginUrl" value="/login.jsp"></property>
- 15 <!-- 登录成功后要跳转的连接(此处已经在登录中处理了) -->
- 16 <!-- <property name="successUrl" value="/index.jsp"></property> -->
- 17 <!-- 未认证时要跳转的连接 -->
- 18 <property name="unauthorizedUrl" value="/refuse.jsp"></property>
- 19 <!-- shiro连接约束配置 -->
- 20 <property name="filterChainDefinitions">
- 21 <value>
- 22 <!-- 对静态资源设置允许匿名访问 -->
- 23 /images/** = anon
- 24 /js/** = anon
- 25 /CSS/** = anon
- 26 <!-- 可匿名访问路径,例如:验证码、登录连接、退出连接等 -->
- 27 /auth/login = anon
- 28 <!-- 剩余其他路径,必须认证通过才可以访问 -->
- 29 /** = authc
- 30 </value>
- 31 </property>
- 32 </bean>
- 33
- 34 <!-- 配置shiro安全管理器 -->
- 35 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- 36 <property name="realms" ref="customRealm"></property>
- 37 </bean>
- 38
- 39 <!-- 自定义Realm -->
- 40 <bean id="customRealm" class="com.zxz.auth.realm.UserRealm">
- 41 <property name="credentialsMatcher" ref="credentialsMatcher"></property>
- 42 </bean>
- 43
- 44 <!-- 配置凭证算法匹配器 -->
- 45 <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
- 46 <!-- Md5算法 -->
- 47 <property name="hashAlgorithmName" value="Md5"></property>
- 48 </bean>
【高能说明:以上俩个配置文件中加粗画线的红色部分必须一致,没毛病。】
还需要说明的是,在上面的配置文件中 shiro 连接约束配置那块,要特别小心,哥们我就在哪块吃了 2 天的折磨亏,当时是只配置了 /** = authc,没有配置可匿名访问的路径,当时是什么情况吧,就是无限次的调试无限次的修改,我是真长记性了,还有一点就是在配置的时候把你项目中的静态资源放开,被屏蔽了啊,好心提醒,不谢。
4、当然,在这之前,还要编写自定义 realm 类,该类必须认 AuthorizingRealm 类做爸爸,不然你是不行滴,之后还有俩个儿子需要处理了,一个是认证另一个授权,理论我就不多说了,MD 没用。
- 1 public class UserRealm extends AuthorizingRealm {
- 2 3@Autowired 4 private UserService userService;
- 5 6@Override 7 public String getName() {
- 8
- return "customRealm";
- 9
- }
- 10 11
- /**
- 12 * 认证
- 13 */
- 14@Override 15 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- 16 // 获取用户名称
- 17 String username = (String) token.getPrincipal();
- 18 User user = userService.findByUsername(username);
- 19
- if (user == null) {
- 20 // 用户名不存在抛出异常
- 21 System.out.println("认证:当前登录的用户不存在");
- 22
- throw new UnknownAccountException();
- 23
- }
- 24 String pwd = user.getPassword();
- 25
- return new SimpleAuthenticationInfo(user, pwd, getName());
- 26
- }
- 27 28
- /**
- 29 * 授权
- 30 */
- 31@Override 32 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection princ) {
- 33
- return null;
- 34
- }
- 35
- }
5、到这儿,shiro 安全框架的整合是完成了,然后编写 action 类来实现登录功能,不多说了,直接上代码。
- 1
- /**
- 2 * shiro框架登录
- 3 * @param user
- 4 */
- 5@RequestMapping(value = "/login", method = RequestMethod.POST) 6 public ModelAndView login(User user) {
- 7 // 表面校验
- 8
- if (!StringUtil.isNullOrBlank(user.getUsername()) || !StringUtil.isNullOrBlank(user.getPassword())) {
- 9
- return new ModelAndView("login") 10.addObject("message", "账号或密码不能为空") 11.addObject("failuser", user);
- 12
- }
- 13 // 获取主体
- 14 Subject subject = SecurityUtils.getSubject();
- 15
- try {
- 16 // 调用安全认证框架的登录方法
- 17 subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
- 18
- } catch(AuthenticationException ex) {
- 19 System.out.println("登陆失败: " + ex.getMessage());
- 20
- return new ModelAndView("login") 21.addObject("message", "用户不存在") 22.addObject("failuser", user);
- 23
- }
- 24 // 登录成功后重定向到首页
- 25
- return new ModelAndView("redirect:/index");
- 26
- }
最后需要给大家说的就是,当某用户登录成功之后,shiro 安全框架就会将用户的信息存放在 session 中,你可以通过 User user = (User) SecurityUtils.getSubject().getPrincipal(); 这句代码在任何地方任何时候都能获取当前登录成功的用户信息。
很长年间没用 shiro 安全框架了,原理忘得都差不多了,但是驾驭它还是没问题的,如果哪儿写的不对的,希望各位指教,尽管我脾气很爆,哈哈哈。
来源: http://www.cnblogs.com/1315925303zxz/p/6874219.html