SSM整合shiro实现认证和授权的简单案例

本文详细介绍了如何在SSM框架中整合Shiro进行权限认证,包括配置Shiro的依赖、在web.xml中配置Shiro过滤器、配置spring-shiro.xml、重写AuthorizingRealm及控制器代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.首先要搭建SSM框架

2.引入ssm相关依赖

<!--shiro相关依赖-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-quartz</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.2.2</version>
    </dependency>

基本ssm框架整合其他技术都是在spring中引入一个bean实现整合(小白自己的理解)

3.在web.xml中配置shiro的

 <!--shiro的filter-->
    <!--shiro过滤器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由Servlet容器管理控制filter的生命周期 -->
            <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>

shiro也是通过过滤器进行拦截的,filter进行拦截过后找到spring中所配置的过滤链,shiro中提供了很多filter

4.配置spring-shiro

 <!-- Shiro 的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!--配置登录界面-->
        <property name="loginUrl" value="/login.action" />
        <!--配置成功认证后跳转的url只是附属配置,实际上跳转的是上一次请求的url-->
        <property name="successUrl" value="/index.jsp"/>
        <!--认证未成功跳转的界面-->
        <property name="unauthorizedUrl" value="/index.jsp" />
        <!--引入自己定义的重写了表单过滤器的过滤器-->
        <property name="filters">
            <map>
                <entry key="authc" value-ref="formAuthenticationFilter" />
            </map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /login.action=authc
            </value>
        </property>
    </bean>
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm" />
    </bean>
    <!-- 自定义 realm -->
    <bean id="userRealm" class="realm.CustomRealm"/>
    <!--重写的表单过滤器-->
    <bean id="formAuthenticationFilter" class="filter.MyFormAuthenticationFilter">
        <property name="loginUrl" value="/login.action"/>
    </bean>
</beans>

其中有几点需要注意:

1. 配置的LoginURL就是登录界面, 而不是表单的提交界面

2.successURL只是 一种附属配置,当认证成功后session中保存的是上一次 请求的URL, 所以认证成功后并不会跳转到successurl,而是跳转到上一次 请求的URL也就是返回Loginurl登陆界面。一正常情况下成功返回login,在controller中处理失败跳转的页面。当然也可以通过重载 formauthenticafilter的方法来实现successURL的跳转

3.shiro中的过滤器

208783.jpg

5.重写authorizingrealm

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Override
    public String getName() {
        return "CustomRealm";
    }
    /*实现授权的方法*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userCode=(String)principals.getPrimaryPrincipal();
        List<String> role=userService.role(userCode);
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(role);
        return simpleAuthorizationInfo;
    }
    /*实现认证的方法*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
       /*从token中取出用户凭证*/
        String userCode=(String)token.getPrincipal();
        User user=userService.login(userCode);
        System.out.println(user);
        if(user!=null){
            String password=user.getPassword();
            System.out.println(password);
                SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password, this.getName());
                return simpleAuthenticationInfo;
        }
        return null;
    }
}

6.controller

 @RequestMapping(value = "/check.action")
    public String check(@RequestParam("username")String username,@RequestParam("password")String password) {
        if(username!=null && password!=null){
            Subject subject= SecurityUtils.getSubject();
            UsernamePasswordToken token=new UsernamePasswordToken(username,password);
            try{
                subject.login(token);
                return "success";
            }catch (Exception e){
                e.printStackTrace();
            }
        }else{
            System.out.println("请输入用户名或密码");
        }
        return "login";
    }

shiro认证的总结: 用户登录是在一个表单中进行的,所以需要通过shiro的一个表单过滤器(formauthenticationfilter)进行实现的,其原理如下:

用户没有认证时,请求Loginurl进行认证,输入信息后点击提交数据到LoginURL,然后formauthenticationfilter过滤器进行拦截取出其中的username和password(表单中的用户名和密码智能是username和password), 如果想改动的话可以在spring-shiro文件中进行配置formauthenticationfilter重新对其命名。然后formauthenticationfilter会调用realm传入一个token(token里面封装这用户信息),realm认证时根据username在数据库只能怪查询用户信息,然后返回一个SimplAuthenticationInfo(进行校验)。

 

 

有些controller代码只处理 错误信息返回错误界面,controller中

Subject subject= SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
subject.login(token);

其实在formauthenticationfilter内部 就已经调用了的。但是我把loginurl配置成登录界面formauthenticationfilter根本就不进行拦截,所以根本不能进入realm,所以 只能在controller中自己 动手获取username和password然后login()。如果有大牛知道哪里错的话,希望能够帮忙指点哪里不对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值