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项目运行jar包启动的步骤流程解析

    下面是关于SpringBoot项目运行jar包启动的步骤流程解析的完整攻略。 1. 编写SpringBoot应用程序 首先,我们需要编写一个SpringBoot应用程序。这里以一个简单的Hello World程序为例: @RestController public class HelloController { @GetMapping("/hell…

    Java 2023年5月19日
    00
  • Apache和Tomcat有什么区别_动力节点Java学院整理

    Apache和Tomcat有什么区别_动力节点Java学院整理 简介 Apache和Tomcat都是常见的Java Web服务器。它们的区别在于它们的作用以及它们处理请求的方式。Apache是一个Web服务器,它通过HTTP和HTTPS协议分发静态文件和动态文件,而Tomcat是一个Servlet容器,它只能在动态资源请求时运行Servlet。在实际应用开发…

    Java 2023年5月20日
    00
  • MyBatis基于pagehelper实现分页原理及代码实例

    下面是”MyBatis基于pagehelper实现分页原理及代码实例”的完整攻略。 1. 什么是PageHelper PageHelper是一个开源的MyBatis分页插件,它能够实现对MyBatis查询结果的分页操作。PageHelper可以自动进行物理分页,通过PageHelper提供的简单接口,我们能够不必手动编写复杂的分页语句,从而快速地实现数据的分…

    Java 2023年6月15日
    00
  • java利用正则表达式处理特殊字符的方法实例

    当处理含有特殊字符的字符串时,我们通常会使用正则表达式来进行匹配和替换。而Java提供了了解处理特殊字符的方法,并且使用正则表达式来匹配和替换字符串。下面是详细的步骤: 1. 使用转义字符 当需要处理特殊字符(例如:. 、^、$、+、*、?、{、}、(、)、|、\、[、]等)时,需要借助转义字符来进行正则表达式的编写。 示例: String input = …

    Java 2023年5月27日
    00
  • Java 配置加载机制详解及实例

    Java 配置加载机制详解及实例 在 Java 中,配置文件被广泛用于存储应用程序的配置信息。应用程序在启动时需要读取配置文件并使用其中的参数。如果你使用 Java 编写应用程序,你需要掌握 Java 中的配置文件的加载机制。 配置文件的加载机制 Java 中的配置文件可以使用多种格式,如 .properties、.xml、.json 等。在加载配置文件时,…

    Java 2023年6月2日
    00
  • spring学习之创建项目 Hello Spring实例代码

    创建 Spring 项目 Hello Spring 实例代码的完整攻略包括以下步骤: 1. 创建 Maven 项目 使用 Maven 作为构建工具,创建一个 Spring 项目。可以使用 mvn archetype:generate 命令快速创建一个 Maven 项目,输入 maven-archetype-webapp 可以创建一个 Java Web 项目。…

    Java 2023年5月31日
    00
  • 一文搞懂Java顶层类之Object类的使用

    一文搞懂Java顶层类之Object类的使用 简介 在Java中,所有类都有一个共同的父类,即Object类。Object类定义了所有Java对象的通用行为。Object类中包含了许多常用的方法,例如toString()、equals()等。本文将详细讲解Object类的使用。 Object类的通用方法 toString() toString()方法用于返回…

    Java 2023年5月26日
    00
  • java.lang.String类的使用

    Java.lang.String类的使用 java.lang.String 类是 Java 标准库中最常用的类之一,用于表示字符串。本篇攻略旨在帮助读者全面了解 String 类的使用方法,并且提供几个示例说明。 基本使用 String 对象是不可变的,也就是说一旦创建了 String 对象,它的值将不能被更改。使用 String 类最基本的方法是创建一个新…

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