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安全框架了,原理忘得都差不多了,但是驾驭它还是没问题的,如果哪儿写的不对的,希望各位指教,尽管我脾气很爆,哈哈哈。