Spring integrates Shiro, SpringBoot integrates Shiro

Shiro

Three major functions of Shiro

Shiro has three core components, namely Subject, SecurityManagerandRealm

  • Subject : for 认证主体. The object that application code interacts with directly is Subject, which represents the current user. Contains Principalsand Credentialstwo messages.
  • SecurityManager : for 安全管理员. It is the core of Shiro architecture. All interactions with the Subject will be delegated to the SecurityManager. The Subject is equivalent to a facade, and the SecurityManager is the real executor. It is responsible for interacting with other components of Shiro.
  • Realm : Yes 一个域. Acts as a "bridge" between Shiro and application security data. Shiro obtains security data (such as users, roles, permissions) from Realm. That is to say, if SecurityManager wants to verify the user's identity, it needs to obtain the corresponding user from Realm for comparison to determine whether the user's identity is legal; it also needs to obtain it from Realm. The user's corresponding roles and permissions are used to verify whether the user's operation can be carried out. Realm can be regarded as a DataSource, that is, a secure data source.

f1df3b80052a40ecb8482475e35e127f~tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

  • Authentication : Identity authentication, login, verifying whether the user has the corresponding identity;
  • Authorization : authorization, that is, authority verification, to verify whether an authenticated user has a certain authority, that is, to determine whether the user can perform any operations, such as verifying whether a user has a certain role, or fine-grained verification of a user Do you have certain permissions on a certain resource?
  • Session Manager : Session management, that is, after the user logs in, it is the first session. Before exiting, all its information is in the session; the session can be an ordinary JavaSE environment or a Web environment;
  • Cryptography : Encryption to protect the security of data, such as passwords being encrypted and stored in the database instead of being stored in clear text;
  • Web Support : Web support, which can be easily integrated into the Web environment;
  • Caching : Caching, for example, after a user logs in, his user information, roles, and permissions do not need to be checked every time, which can improve efficiency.
  • Concurrency : Shiro supports concurrent verification of multi-threaded applications, that is, if you start another thread in one thread, the permissions can be automatically propagated to it.
  • Testing : Provide testing support;
  • RunAs : Allows one user to pretend to be another user (if they allow it);
  • Remember Me : Remember me, this is a very common function, that is, after logging in once, you don’t need to log in next time.

Shiro architecture (external)

b00b0b78d68943feae4aa9832b82bb98~tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

Looking at Shiro from the outside, that is, observing how to use shiro to complete work from the perspective of the application: Subject user, SecurityManager manages all user Realm connection data

  • subject : The object that the application code directly interacts with is Subject. In other words, Shirothe core of the external API is Subjectthat Subject represents the current user. This user is not necessarily a specific person. Anything that interacts with the current application is Subject, such as the network. All interactions with crawlers, robots, etc. with Subject will be delegated to SecurityManager; Subject is actually a facade, and SecurityManageer is the actual executor.
  • SecurityManager : Security manager, that is, all security-related operations will SercurityManagerinteract with it, and it manages all Subjects. It can be seen that it is the core of Shiro. It is responsible for interacting with other components of Shiro. It is equivalent to SpringMVC's DispatcherServlet character of
  • Realm : Shiro obtains security data (such as users, roles, permissions) from Realm. That is to say, if SecurityManager wants to verify the user's identity, it needs to obtain the corresponding user from Realm for comparison to determine whether the user's identity is legal; it also needs to obtain the user from Realm Realm. Corresponding roles and permissions are used to verify whether the user's operation can be carried out. You can view Realm as DataSource;

Shiro architecture (internal)

8991ce3120e94c9baccc4aae76666875~tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

  • Subject : Any user who can interact with the application;
  • Security Manager : Equivalent to SpringMVC DispatcherSerlet; it is Shiro 心脏. All specific interactions Security Managerare controlled through it. It manages all Subjects and is responsible for authentication, authorization, session, and cache management.
  • Authenticator : Responsible for Subjectauthentication, it is an extension point that can be customized; it can be used 认证策略(Authentication Strategy), that is, under what circumstances is the user authentication passed?
  • Authorizer : Authorizer, that is, access controller, used to determine whether the subject has permission to perform corresponding operations; that is, it controls which functions in the application the user can access;
  • Realm : There can be one or more realms, which can be considered as a secure entity data source, that is, used to obtain secure entities. It can be implemented using JDBC, or it can be implemented in memory, etc., and is provided by the user; therefore, it is generally Every application needs to implement its own realm
  • SessionManager : A component that manages the Session life cycle. Shiro can not only be used in the Web environment, but also in the ordinary JavaSE environment.
  • CacheManager : Cache controller to manage caches such as users, roles, permissions, etc. Because these data rarely change, placing them in the cache can improve access performance;
  • Cryptography : cryptography module, Shiro improves some common encryption components for password encryption, decryption, etc.

shiro certification process

W%A~CHW4PLQ`@4B%1@KF4Y0.png

shiro authorization process

b418716f335d4f10bde6a62cfa97fa3f~tplv-k3u1fbpfcp-watermark.png

Shiro uses

SaaSExport practice project usage (ssm)

pom.xml dependencies

 
 

xml

Copy code

<!--Shiro和Spring整合--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <!--Shiro核心包--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency>

web.xml

 
 

xml

Copy code

<!--服务器启动时加载Spring配置文件--> <context-param>   <param-name>contextConfigLocation</param-name>   <param-value>     classpath:spring.xml     classpath:shiro.xml   </param-value> </context-param>   <!--Shiro核心过滤器--> <filter>   <filter-name>shiroFilter</filter-name>   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping>   <filter-name>shiroFilter</filter-name>   <url-pattern>/*</url-pattern> </filter-mapping>

shiro.xml

 
 

xml

Copy code

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> ​   <!--id=shiroFilter不能写错,大小写敏感,这个id的值与filter的名字相同-->   <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">       <property name="securityManager" ref="defaultWebSecurityManager"/>       <!--**表示当前路径下所有资源,包括一级目录,二级目录,等等-->       <!--anon放在最前面,authc放在最后面-->       <property name="filterChainDefinitions">           <value>               /css/** = anon               /img/** = anon               /make/** = anon               /plugins/** = anon               /login.do = anon ​               /system/dept/list.do = perms["部门管理"]               /system/user/list.do = perms["用户管理"]               /system/company/list.do = perms["企业管理"]               /system/module/list.do = perms["模块管理"]               /system/role/list.do = perms["角色管理"]               /system/syslog/list.do = perms["日记管理"] ​               /** = authc           </value>       </property>       <property name="unauthorizedUrl" value="/unauthorized.jsp"/>   </bean> ​ ​   <bean id="defaultWebSecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">       <property name="realm" ref="authReaml"/>   </bean> ​ ​   <bean id="authReaml" class="com.it.shiro.AuthReaml"> <!--       &lt;!&ndash;将123456转成MD5格式的密码,然后再和数据库中的MD5密码进行比较&ndash;&gt;--> <!--       &lt;!&ndash;所以在企业开发中,配置方式很常用,可拔插&ndash;&gt;--> <!--       <property name="credentialsMatcher" ref="hashedCredentialsMatcher"/>-->   </bean> ​   <!--我们使用MD5加密器--> <!--   <bean id="hashedCredentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">--> <!--       <property name="hashAlgorithmName" value="MD5"/>--> <!--   </bean>--> ​ ​ </beans>

Permission parameter table

QQ picture 20230807165205.png

Implement class AuthReaml

The permissions of this exercise project are based on the RBAC model. The user table, role table, module table and two intermediate tables are used to obtain the corresponding role of the user through the intermediate table of user and role, and then the corresponding permissions are obtained through the intermediate table of role and module. This is also a typical anti-three-paradigm data table design (although I have forgotten which three paradigms are, will there be anyone who strictly abides by the three-paradigm to design data tables?)

 
 

java

Copy code

package com.it.shiro; ​ import com.it.model.module.Module; import com.it.model.user.User; import com.it.service.module.ModuleService; import com.it.service.user.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; ​ import java.util.List; ​ /** * 自定义Shiro认证和权授的业务逻辑 */ public class AuthReaml extends AuthorizingRealm {    @Autowired    private UserService userService;    @Autowired    private ModuleService moduleService;    /**     * 认证     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        System.out.println("认证");        //1. 将AuthenticationToken接口强转成UsernamePasswordToken实现类并从中获取用户输入的用户名(邮箱)和密码        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;        String username = token.getUsername();        String password = new String(token.getPassword());//char[]->java.lang.String        //2. 根据用户名(邮箱)去数据库中查询用户是否存在,userDB中有密码        User userDB = userService.findByEmail(username);        //3. 如果用户不存在,就返回null        if(userDB == null){            System.out.println("用户不存在");            return null;       }        System.out.println("uid   "+userDB.getUserId());        System.out.println("password   "+userDB.getPassword()); ​        //4. 如果用户存在,就返回AuthenticationInfo接口的SimpleAuthenticationInfo实现类对象,该对象中封装三个信息:        a)认证后的userDB对象        b)认证后的userDB对象封装的数据库密码        c)Realm的别名,可以为""        AuthenticationInfo info = new SimpleAuthenticationInfo(userDB,userDB.getPassword(),"");        //Shiro会在后台对userDB.getPassword()数据库密码和password用户填写的密码在内存中对比        return info;   } ​    /**     * 授权     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        System.out.println("授权");        //1. 使用SecurityUtils获取Subject对象        Subject subject = SecurityUtils.getSubject();        //2. 使用Subject对象获取User对象        User loginUser = (User) subject.getPrincipal();        //3. 根据用户ID查询该用户可以访问的模块,这里的moduleList集合中Module只有模块名name属性        List<Module> moduleList = moduleService.findModuleByUid(loginUser.getUserId()); //       List<Module> moduleList = moduleService.findByUserId(loginUser.getId());        //4. 遍历模块集合,将每一个模块的编号或名称封装到        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        for (Module module : moduleList) {            //info.addStringPermission("部门管理");            info.addStringPermission(module.getName());       }        //SimpleAuthorizationInfo对象中,以便Shiro内容进行授权控制        //5. 返回SimpleAuthorizationInfo对象        return info;   } ​ ​ }

call method

 
 

scss

Copy code

//1.使用SecurityUtils获取subject对象 Subject subject = SecurityUtils.getSubject(); //2.使用AuthenticationToken接口的UsernamePasswordToken实现类封装用户输入的用户名(邮箱)和密码信息 AuthenticationToken token = new UsernamePasswordToken(username,password); //3.调用subject的login()进行认证,底层调用AuthRealm.doGetAuthenticationInfo()认证方法 subject.login(token); //4. 调用subject的getPrincipal()获取认证后的用户,这个userDB就是数据库的密码 User userDB = (User) subject.getPrincipal(); //5. 将用户放入session中 request.getSession().setAttribute("loginUser",userDB);

SpringBoot usage (excerpted from the Internet)

pom.xml

org.apache.shiro shiro-spring 1.4.1

config configuration

Create a new config package and create ShiroConfig and UserRealm

 
 

typescript

Copy code

@Controller public class ShiroConfig {    //三大核心要素: ​    //ShiroFilterFactoryBean    //第三步:    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();        //设置安全管理器        bean.setSecurityManager(defaultWebSecurityManager);        return bean;   } ​    //DafaultWebSecurityManager    //第二步:    @Bean(name="securityManager")    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();        //关联UserRealm        securityManager.setRealm(userRealm);        return securityManager;   } ​    //创建realm对象,需要自定义类    //第一步:    @Bean    public UserRealm userRealm(){        return new UserRealm();   } }

 
 

scala

Copy code

public class UserRealm extends AuthorizingRealm {    //授权    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        System.out.println("执行了=》授权doGetAuthorizationInfo");        return null;   } ​    //认证    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        System.out.println("执行了=》认证doGetAuthenticationInfo");        return null;   } }

Relevant information

SpringBoot integrates shiro

Guess you like

Origin blog.csdn.net/Trouvailless/article/details/132166281