在web项目中Spring整合Shiro做权限管理以及用户认证、权限缓存(一),

      也是为了自己以后方便记忆,自己看了很久怎么用Shiro去做用户认证以及权限校验,特此把这个过程记录下来。也搜索很多教程都觉得讲的云里雾里,其实最后很大的帮助还是官方文档。或许是博主比较笨,废话不说直接写流程。也不知道对不对,如有不对还希望高人指点一下。

http://shiro.apache.org/spring.html :这个地址是官方整合spring的一个教程,好像只有配置文件,但是我没找到具体代                                                                  码, 具 体例子。所以也不明白。

我写的这个教程建立在你知道了Shiro一些概念,以及一些主要对象的基础上的。

第一步:先说一下Shiro的认证流程吧。这是在网上看的一个视频中讲的,自我感觉讲的很好,因为没有视频中的源码就截了个图

        

其实这个流程可以帮助我们明白Shiro认证的一些过程,下面开始

  1,引入Shrio的相关包以及整合spring的包:

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.5</version>
        </dependency>

2,在web.xml文件中配置Shiro过滤器,

<!-- 添加shiro过滤器 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
		<!-- 该值缺省为false,表示声明周期由SpringApplicationContext管理,设置为true表示 
                   ServletContainer管理 -->
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

3,但是Shiro过滤器又是由Spring容器来管理的,所以我们要在Spring容器中配置一个Shiro过滤器的bean。但是呢其实在Spring配置的是一个工厂bean对象,但是这个工厂bean对象中有很多属性可以设置。其中有个过滤器链,在这个过滤器链中就可以设置对项目资源的权限控制。其中还有个属性是<property name="securityManager" ref="securityManager"/>,这个叫做安全管理器,也是需要我们在Spring容器中去配置的。但是呢在securityManager对象中看到需要注入一个<property name="realm" ref="myRelam"/>,这个是需要我们自己去定义一个类,在下一步中会写。还有一点是<property name="unauthorizedUrl" value="/refused.jsp" />这个属性,说是当没有权限时会自动跳转到这个页面,但是我配置了之后没作用,所以就先注释掉。对于 <property name="loginUrl" value="/index.jsp" />这个属性就不用解释了吧,就是你没有认证成功,就会跳转到这个页面。对于过滤器链中的配置是什么意思应该在初步学习Shiro的认证和授权时就应该就已经知道了。

<!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRelam"/>        
    </bean>


 <!-- shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 身份认证失败,则跳转到登录页面的配置 -->
         <property name="loginUrl" value="/index.jsp" />
        <!-- 权限认证失败,则跳转到指定页面, -->
        <!--<property name="unauthorizedUrl" value="/refused.jsp" /> -->
        <!-- Shiro连接约束配置,即过滤链的定义   authc -->
        <property name="filterChainDefinitions">
            <value>
            	/user/login=anon
            	/static/**=anon
                /index.jsp=anon
                /refused.jsp=anon
                /**=authc
            </value>
        </property>
    </bean>

4,自定义一个realm继承AuthorizingRealm类。(个人理解这个realm就可以干认证和授权的事)里面的代码先不管什么意思             

public class MyRealm extends AuthorizingRealm {
    
   @Autowired
    private UserService userService;

    //这个方法是用来授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
          User user = (User)principalCollection.getPrimaryPrincipal();
          List<String> userPermissions = userService.findUserPermissions(user.getId());
          SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
          authorizationInfo.addStringPermissions(userPermissions);
          log.debug("从数据库中查询");
          return authorizationInfo;
    }
    
    
    //这个方法是用来认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        User user = userService.getUserByName(username);
        if (user == null){
            throw new UnknownAccountException("账户不存在");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),getName());

        return info;
    }
   
}

  4,接下来就可以写认证的Controller了。在controller中不多解释,最重要的就是当执行subject.login(usernamePasswordToken);这个方法的时候,就会执行我们自定义的realm中的认证方法。至于里面是怎么认证的我自己也不是非常的清楚,可以参考一开始的认证流程。如果前端传来的账号密码不匹配,在realm中就会抛出一个异常,然后在controller中捕捉到异常就会提示认证失败,并且还是在inde页面。如果认证成功了,就会执行redirect:/admin/main.jsp 这个转发到系统的首页。到这里用Shiro做认证就算完成了。

@Controller
@RequestMapping("/user")
public class UserAdminController {
    private static final Logger log = Logger.getLogger(UserAdminController.class);// 日志文
	
	
	@RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(User user, Model model) {
	    Subject subject = SecurityUtils.getSubject();
	   /* if (user == null){ return "login";}*///前端已经设置了账号密码不为空

        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(),user.getPassword());
        try {
            subject.login(usernamePasswordToken);
  
        } catch (AuthenticationException e) {
            e.printStackTrace();
            model.addAttribute("msg","账号或密码错误");
            log.info("==============================认证失败");
            return "index";
        }
        log.info("=================================认证成功");
        return "redirect:/admin/main.jsp";

    }

    5,我看到视频上在Controller中是直接判断是否有异常,然后前端页面表单的name值好像也有一些规定。但是我在网上找到有例子是这样写的。所以我就这样做了。如有不对,还希望高人来指点。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值