Spring 应用中集成 Apache Shiro的方法

当在Spring应用中需要使用安全、身份验证等功能时,可以使用Apache Shiro安全框架。下面是在Spring应用中集成Apache Shiro的方法:

第一步:导入相关依赖

在pom.xml文件中,加入Shiro和Spring集成的依赖:

<!-- shiro -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.7.0</version>
</dependency>

<!--Spring-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

第二步:配置shiro.ini

在src/main/resource目录下,新建一个shiro.ini文件,这个文件是Shiro的配置文件,通过配置这个文件来定义Shiro的安全管理器、realm等。

[main]
# 定义 Shiro 的安全管理器
securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager

# 定义 Realm
realm = org.apache.shiro.realm.jdbc.JdbcRealm
realm.authenticationQuery = SELECT password FROM users WHERE username = ?
realm.userRolesQuery = SELECT role FROM user_roles WHERE username = ?
realm.permissionsQuery = SELECT permission FROM roles_permissions WHERE role = ?


# 注册 Realm
securityManager.realms = $realm

# 配置记住我功能的 Cookie
cookie = org.apache.shiro.web.servlet.SimpleCookie
cookie.name = rememberMe
cookie.maxAge = 2592000

# 配置会话管理器
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.globalSessionTimeout = 1800000
sessionManager.deleteInvalidSessions = true
sessionManager.sessionValidationSchedulerEnabled = true

# 配置缓存管理
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml

# 将 securityManager 交由 Spring 管理
securityManager.sessionManager = $sessionManager
securityManager.cacheManager = $cacheManager
WebSecurityManager = $securityManager

[users]
admin = 123456,admin
guest = 123456,guest

[roles]
admin = *
guest = user:query

[urls]
/login.jsp = anon
/logout.jsp = logout
/** = authc

第三步:使用Shiro的FilterChain

在Spring的xml文件中定义Shiro的Filter,如下:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="WebSecurityManager"/>
    <property name="loginUrl" value="/login.html"/>
    <property name="successUrl" value="/index.html"/>
    <property name="unauthorizedUrl" value="/error.html"/>

    <property name="filterChainDefinitionMap">
        <map>
            <entry key="/login.html" value="anon"></entry>
            <entry key="/logout.html" value="logout"></entry>
            <entry key="/**" value="authc"></entry>
        </map>
    </property>
</bean>

在这个配置中,我们定义了ShiroFilter的Bean,并注入了刚刚定义的WebSecurityManager作为其安全管理器。同时,我们定义了3个属性,分别对应登录的URL、登录成功后的URL、未授权时的URL。

最后我们定义了Url和filterChain的对应关系,通俗点来说就是定义了哪些URL需要进行过滤,哪些不需要过滤。

示例一:基于注解

@Service
public class UserServiceImpl implements UserService {
    @RequiresAuthentication
    @Override
    public void add(User user) {
        userDao.add(user);
    }

    @RequiresAuthentication
    @Override
    public void delete(User user) {
        userDao.delete(user);
    }

    @RequiresRoles("admin")
    @Override
    public void update(User user) {
        userDao.update(user);
    }

    @RequiresPermissions("user:query")
    @Override
    public List<User> query(User user) {
        return userDao.query(user);
    }
}

在这个示例中,我们在Service的实现类中使用到了Shiro的注解功能,对每个方法进行了不同的权限、角色、权限的要求。通过这种方式,我们可以在不需要进行大量手动编写拦截的情况下进行对方法的权限限制。当然,在使用这个功能时,需要在xml中做如下的配置:

<!-- 开启 Shiro 注解支持 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="WebSecurityManager"/>
</bean>

<!-- 开启 AOP 代理 -->
<aop:config proxy-target-class="true"/>
<aop:advisor advice-ref="authorizationAttributeSourceAdvisor"
              pointcut="@annotation(org.apache.shiro.authz.annotation.RequiresAuthentication) or 
              @annotation(org.apache.shiro.authz.annotation.RequiresPermissions) or 
              @annotation(org.apache.shiro.authz.annotation.RequiresRoles)"/>

其中,定义了一个authorizationAttributeSourceAdvisor,作为一个advisor的配置,指定了三个切入点,分别对应了Shiro的三个注解。这样,当使用到了Shiro注解时,就可以在方法执行之前先判断用户是否满足对应的角色、权限、身份了。

示例二:自定义Realm

public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
        String username = (String) principals.getPrimaryPrincipal();
        User user = userService.getUserByName(username);
        if (user != null) {
            List<Role> roles = user.getRoles();
            if (roles != null) {
                for (Role role : roles) {
                    authInfo.addRole(role.getName());
                    List<Permission> permissions = role.getPermissions();
                    if (permissions != null) {
                        for (Permission permission : permissions) {
                            authInfo.addStringPermission(permission.getName());
                        }
                    }
                }
            }
        }
        return authInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        User user = userService.getUserByName(username);
        if (user == null) {
            throw new UnknownAccountException("用户名不存在");
        }
        SimpleAuthenticationInfo authInfo =
                new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        return authInfo;
    }
}

这个示例中,我们自定义了一个Realm,并继承了AuthorizingRealm。在这个Realm中,我们指定了验证身份和权限的方法,同时注入了UserService,通过它来获取用户、角色、权限等信息。

最后,在xml中我们需要做如下的配置:

<!-- 注册自定义的 Realm -->
<bean id="myRealm" class="com.example.MyRealm">
    <property name="permissionResolver" ref="myPermissionResolver"/>
    <property name="credentialsMatcher" ref="myCredentialsMatcher"/>
</bean>

<!-- 配置 RememberMeCookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg value="rememberMe"/>
    <property name="maxAge" value="2592000"/>
</bean>

<!-- 配置 RememberMeManager -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    <property name="cookie" ref="rememberMeCookie"/>
</bean>

<!-- 配置 RememberMeConfig -->
<bean id="rememberMeConfig" class="org.apache.shiro.web.config.RememberMeConfig">
    <property name="rememberMeEnabled" value="true"/>
    <property name="rememberMeManager" ref="rememberMeManager"/>
</bean>

<!-- 配置 SecurityManager -->
<bean id="webSecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
    <property name="sessionManager" ref="sessionManager"/>
    <property name="cacheManager" ref="cacheManager"/>
    <property name="rememberMeManager" ref="rememberMeManager"/>
</bean>

在这个配置中,我们定义了自定义的Realm,并将其注入到了WebSecurityManager中。同时,还为了方便记住密码的功能,定义了RememberMeCookie、RememberMeManager、RememberMeConfig,并在WebSecurityManager中注入了RememberMeManager。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring 应用中集成 Apache Shiro的方法 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • SpringBoot + Spring Security 基本使用及个性化登录配置详解

    SpringBoot+SpringSecurity基本使用 1. 引入Spring Security 在pom.xml中添加Spring Security的依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sprin…

    Java 2023年5月15日
    00
  • 什么是受检异常?

    什么是受检异常? 在Java中,对于可能会导致程序错误的代码,我们有时会在代码中使用异常机制进行处理,使得程序在运行时遇到问题时可以从异常处理代码块中恢复,继续执行后面的程序。而受检异常(Checked Exception)就是其中一种异常类型,它需要在代码中进行显式的处理,否则编译时就会报错。 受检异常的特点 受检异常与非受检异常(Unchecked Ex…

    Java 2023年4月27日
    00
  • SpringBoot项目创建使用+配置文件+日志文件详解

    Spring Boot项目创建使用+配置文件+日志文件详解 Spring Boot是一个非常流行的Java框架,它提供了许多自动配置功能,使得开发人员可以更快速地构建应用程序。在本文中,我们将深入探讨Spring Boot项目的创建、使用、配置文件和日志文件的详解。 Spring Boot项目创建 Spring Boot项目的创建非常简单,可以通过以下步骤完…

    Java 2023年5月15日
    00
  • java实现简单的ATM项目

    Java实现简单的ATM项目攻略 1. 确定项目需求 在开发ATM项目之前,我们需要明确项目的需求以及功能,以便为项目建立蓝图。 1.1 项目需求 用户登录,包括账户名和密码验证 存款和取款 查询余额 修改密码 银行卡挂失/解挂 退出系统 1.2 功能 用户登录:用户需要输入账号和密码进行登录。 存款和取款:用户可以选择存款或取款操作并输入具体金额。 查询余…

    Java 2023年5月19日
    00
  • RateLimit-使用guava来做接口限流代码示例

    为保护服务器的正常运行和客户端的正常使用,我们需要对接口进行访问限制。本文介绍了使用Guava RateLimit实现接口限流的代码示例。 Guava RateLimit简介 Guava是由Google开发的Java类库,其中包含了RateLimiter类,可用于接口限流。RateLimiter可以用于限制一定时间内的请求频率,比如每秒钟只能处理10个请求。…

    Java 2023年5月19日
    00
  • Java实现一致性Hash算法详情

    Java实现一致性Hash算法 什么是一致性哈希算法? 一致性哈希算法是一种分布式哈希算法,常用于分布式缓存、分布式数据库等场景,主要解决如何有效地将请求路由到不同的服务器,从而提高系统性能。 一致性哈希算法的原理 一致性哈希算法将每个资源映射到一个二维环上,即将环划分为若干个虚拟节点。当有新的数据需要放入缓存中时,首先将该数据哈希成一个数字,然后将该数字映…

    Java 2023年5月19日
    00
  • 小程序实现授权登陆的解决方案

    小程序实现授权登录的解决方案是比较复杂的,需要涉及到小程序端和服务端两个方面。在授权登录的过程中,小程序端需要获取用户的授权信息,并将授权信息发送给服务端进行校验,服务端校验成功之后再将返回的用户信息返回给小程序端。以下是实现授权登录的完整攻略: 步骤一:获取用户授权 在小程序中调用 wx.login() 方法获取 code,这个 code 会在后续用来获取…

    Java 2023年5月23日
    00
  • Java实现超市会员管理系统

    Java实现超市会员管理系统攻略 准备工作 安装Java开发环境:推荐使用Eclipse或IntelliJ IDEA等集成开发环境。 了解Java GUI开发框架:Java Swing。 选择数据库:常用的关系型数据库有MySQL、Oracle、SQL Server等,非关系型数据库有MongoDB、Redis等。 功能设计 根据超市的实际情况,确定要实现的…

    Java 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部