shiro security framework

Rights management: Rights management is required for systems involving user participation. Rights management belongs to the category of system security. Rights management is to realize the control of user access to the system. Users can be controlled according to security rules or security policies, and users can only access their own users. Authorized resources.

Rights management includes two parts: user==authentication==and==authorization==, referred to as ==authentication and authorization==. For resources that need access control, users must first undergo identity authentication. After the authentication is passed, users can access the resources only after they have access rights to the resources.

Identity authentication: Verify whether the user's identity is legal. The most commonly used simple identity authentication method is that the system checks whether the user name and password entered by the user are consistent with the user's user name and password stored in the system to determine whether the user's identity is correct. . An example in life: if a system such as a fingerprint is used, the fingerprint should be shown; for a card-swiping system such as a hardware Key, a card should be swiped.

==Authorization, that is, access control==, controls who can access which resources. After the subject performs == identity authentication == needs to be assigned permissions to access the resources of the system, some resources cannot be accessed without permission

Shiro is an authentication and authorization framework. Shiro can easily develop good enough applications, which can be used not only in the JavaSE environment, but also in the JavaEE environment. Shiro can help us with: authentication, authorization, encryption, session management, integration with the Web, caching, etc.

1. shiro's certification work

1.1, the key objects of authentication in shiro

Subject: Subject The user who accesses the system, the subject can be a user, a program, etc., and the authentication is called the subject;

Principal: Identity information - Account is the identity of the subject for authentication. Identity must be unique, such as user name, mobile phone number, mailbox address, etc. A principal can have multiple identities, but must have a principal Identity.

credential: credential information---password is security information that only the subject knows, such as passwords, certificates, etc.

1.2. Certification process

1.3 Authentication in Java (without database connection)

1.3.1 Create a maven project and add dependencies

 <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.9.0</version>
        </dependency>

1.3.2 Create ini file

This option is in txt format

1.3.3 Test code

 public static void main(String[] args) {
        //1. Get the SecutiryManager object
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2. Read the ini file
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        //3. Set the realm of securityManager
        securityManager.setRealm(iniRealm);
        //4. Set the securityManager context to take effect
        SecurityUtils.setSecurityManager(securityManager);

        //5. Get the subject object
        Subject subject= SecurityUtils.getSubject();
        try {
            //The role of UsernamePasswordToken is to encapsulate the account number and password you entered. It is the account number and password entered by the customer.
            UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456");
            //Throwing an exception, realm compares your own comparison in shiro
            subject.login(token);
            System.out.println("login successful");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Incorrect username or password");
        }



    }

1.3.4 Authentication Principle

Subject: Subject The login information is submitted to the SecurityManager, --->Authenticator---->According to the data provided by your realm to perform related authentication. realm---a class that interacts with the data source.

2. Authorization

2.1 Authorization Flowchart

 

 

2.2 Modification of the code

   public static void main(String[] args) {
        //1. Get the SecutiryManager object
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
//        //2. Read the ini file
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        //3. Set the realm of securityManager
        securityManager.setRealm(iniRealm);
        //4. Set the securityManager context to take effect
        SecurityUtils.setSecurityManager(securityManager);

        //5. Get the subject object
        Subject subject= SecurityUtils.getSubject();
        try {
            //The role of UsernamePasswordToken is to encapsulate the account number and password you entered. It is the account number and password entered by the customer.
            UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456");
            //Throwing an exception, realm compares your own comparison in shiro
            subject.login(token);
            System.out.println("login successful");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Incorrect username or password");
        }
       // subject.logout();
        System.out.println("====================================================after login=====================================");
        boolean authenticated = subject.isAuthenticated();
        if(authenticated){
            //Determine whether the current login has the user:query permission
            boolean permitted = subject.isPermitted("user:update");
            System.out.println(permitted);
            //From a role perspective
            boolean b = subject.hasRole("role1");
            System.out.println(b);
        }else{
            System.out.println("Please authenticate first");
        }
    }

3. The underlying code of authentication

 

We analyze the source code and send our final authentication to realm to complete the authentication function and return an info. If the info is not null, the password is compared. If we use the account and password in the database to complete the authentication function, we need to customize a class and inherit AuthenticatingRealm.

4. Customize Realm Authentication

 private UserService userService=new UserService();
    //This method is used to complete the authentication function
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1. Obtain an account according to the token
        String username = (String) authenticationToken.getPrincipal();
        //2. Query user information according to the account
        User user = userService.findByUsername(username);
        if(user!=null){
            //password obtained from the database
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
            return info;
        }
        return null;
    }

 

5. Encryption

shiro it provides a lot of medium ciphers. The other most used is HashedCredentialsMatcher. Its bottom layer still uses Md5 encryption. Learn about MD5 encryption

 

  public static void main(String[] args) {
        //source: plaintext to be encrypted
        Md5Hash md5Hash = new Md5Hash("123456");
        System.out.println(md5Hash);//e10adc3949ba59abbe56e057f20f883e ciphertext---default md5 encryption is irreversible. But there are some cracked software on the Internet

        //salt: salt
        Md5Hash md5Hash1=new Md5Hash("123456","abc?!");
        System.out.println(md5Hash1);

        //Set n encryption
        Md5Hash md5Hash2 = new Md5Hash("123456","abc?!",1024);

    }

5.1 shiro uses a password encryptor

Modify realm code

 

6. Customize the authorization function of realm

   private UserService userService = new UserService();
    //When to execute this method: This method will be executed when you perform permission verification
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       User user = (User) principalCollection.getPrimaryPrincipal();
        //Query which permissions the user has based on the account
        List<String> list= userService.findPermissionByUsername(user.getUsername());
        if(list!=null&&list.size()>0){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            info.addStringPermissions(list);
            return info;
        }
        return null;
    }

    //
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1. Obtain an account according to the token
        String username = (String) authenticationToken.getPrincipal();
        //2. Query user information according to the account
        User user = userService.findByUsername(username);
        if(user!=null){
            //password obtained from the database
            ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSalt,this.getName());
            return info;
        }
        return null;
    }

test code

 DefaultSecurityManager securityManager=new DefaultSecurityManager();

        MyRealm myRealm=new MyRealm();
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        myRealm.setCredentialsMatcher(credentialsMatcher);

        securityManager.setRealm(myRealm);

        SecurityUtils.setSecurityManager(securityManager);


        Subject subject = SecurityUtils.getSubject();

        try {
            UsernamePasswordToken token = new UsernamePasswordToken("ykq", "123456");
            subject.login(token);

            System.out.println(subject.isPermitted("user:query"));
            System.out.println(subject.isPermitted("user:update"));

        }catch (Exception e){
            System.out.println("Account password error");
        }

    }

7. ssm integration shiro

7.1. Integration steps

(1) Introduce dependencies

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

(2) Modify the spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--packet scan-->
    <context:component-scan base-package="com.wk"/>
    <!--Turn on annotations-->
    <mvc:annotation-driven/>
    <!--Release of static resources-->
    <mvc:default-servlet-handler/>
    <!-- start up Shrio annotations shiro Add in to controller should belong to springmvc Configuration -->
    <bean id="lifecycleBeanPostProcessor"
          class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor" />
    <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>
    <!--spring Configuration-->
    <!--Data source configuration-->
    <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
        <!--driver name-->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="123456de"/>
        <!--Initialize the number of connection pools-->
        <property name="initialSize" value="5"/>
        <!--at least the number-->
        <property name="minIdle" value="5"/>
        <!--maximum number-->
        <property name="maxActive" value="10"/>
        <!--Maximum wait time in milliseconds-->
        <property name="maxWait" value="3000"/>
    </bean>

    <!--sqlSessionFactory Integrate mybatis-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="ds"/>
        <!--set up mybatis path to map file-->
        <!--        <property name="mapperLocations" value="classpath:mapper/*.xml"/>-->
        <!---->
    </bean>

    <!--for dao Interface generation proxy implementation class-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--for com.ykq.dao The interface under the package generates the proxy implementation class-->
        <property name="basePackage" value="com.wk.dao"/>
    </bean>

    <!--transaction management-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"/>
    </bean>
    <!--Enable transaction management-->
    <tx:annotation-driven transaction-manager="transactionManager"/>


    <!--Integrate shiro config content-->
    <!--①SecurityManager-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="realm"/>
    </bean>
    <!--Create custom realm class object-->
    <bean id="realm" class="com.wk.realm.MyRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher"/>
    </bean>

    <!--Create a password matcher-->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="MD5"/>
        <property name="hashIterations" value="1024"/>
    </bean>

    <!--shiro filter factory: set filtering rules-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--If not logged in, the path to jump to-->
        <property name="loginUrl" value="/login.jsp"/>
        <!--No permission, jump path  -->
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <property name="filterChainDefinitions">
            <value>
                /login=anon
                /**=authc
            </value>
        </property>
        <property name="filters">
            <map>
                <entry key="authc">
                    <bean class="com.wk.filter.LoginFilter"/>
                </entry>
            </map>
        </property>
    </bean>




</beans>

Modify the web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

  <!--shiro filter proxy-->
  <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>


  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--when tomcat Created at startup DipatcherServlet Default when accessing controller path created-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

Modify the controller layer

7.2 Authorize users

 

This method is not secure, and users can still access after knowing the path of other permissions.

So we need to intercept, if the user does not have a certain permission, he cannot access the permission.

7.2.1 Access interception

  1. Interceptor---Get the request path and then judge whether the current user has the permission based on your path.

  2. spring provides an annotation when integrating shiro: you can load the corresponding method.

 

1. Turn on shiro annotations
<!-- Start Shrio's annotations -->
    <bean id="lifecycleBeanPostProcessor"
          class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor" />
    <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

2. Use shiro annotations
  @RequiresPermissions(value = {"/user/query","/user/aaa"},logical= Logical.OR)

 

We learned about global exception handling:

Related code demo

Annotations opened in springmvc

 

@RestController
@RequestMapping("/user")
public class UserController {

    //The default spring framework does not recognize this annotation.  This annotation needs to be turned on in the springmvc configuration file
    @GetMapping("/query")
    @RequiresPermissions(value = {"/user/query"},logical= Logical.OR)
    public String query(){

        return "user:query";
    }

    @GetMapping ("/update")
    @RequiresPermissions(value = {"/user/update"})
    public String update(){

        return "user:update";
    }

    @GetMapping ("/delete")
    @RequiresPermissions(value = {"/user/delete"})
    public String delete(){

        return "user:delete";
    }

    @GetMapping ("/insert")
    @RequiresPermissions(value = {"/user/insert"})
    public String insert(){

        return "user:insert";
    }

    @GetMapping ("/export")
    @RequiresPermissions(value = {"/user/export"})
    public String export(){

        return "user:export";
    }

}

The prompt given when there is no permission

@ControllerAdvice
public class MyException {
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public CommonResult auth(UnauthorizedException e){
        e.printStackTrace();
        return new CommonResult(4002,"Insufficient permissions",null);
    }

}

7.2.2 Without login

 

8. ssm integrates shiro to complete front-end and back-end separation

The so-called front-end and back-end are completely separated: the back-end responds to json data instead of web pages.

1. Login success or failure should return json data
2. When not logged in, it also returns json data
3. Access to unauthorized resources also requires club json.

 

8.1 Login success or failure should return json data

Modify the login interface

 

 

8.2 json data is also returned when not logged in

(1) Create a filter to inherit an interface of login verification

public class LoginFilter extends FormAuthenticationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();

        CommonResult commonResult = new CommonResult(4001, "not logged in", null);
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        writer.print(json); //Response to client with json data
        writer.flush();
        writer.close();
        return false;
    }
}

(2) Register filter

 

8.3 If you don't have permission, you should return json data

 

9, springboot integration shiro

9.1 Related configuration and dependencies

(1) Dependence

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ykq</groupId>
    <artifactId>qy151-springboot-shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>qy151-springboot-shiro</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

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


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

(2) application configuration file

#data source
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#The port number
server.port=8808

#sql log
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

(1) application configuration file

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.HashMap;


@Configuration
public class ShiroConfig {


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(realm());
        return securityManager;

    }

    @Bean
    public Realm realm(){
        MyRealm myRealm=new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

    @Bean(value = "shiroFilter")
    public ShiroFilterFactoryBean filterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());

        //Set blocking rules
        HashMap<String,String> map=new HashMap<>();
        map.put("/login","anon");
        map.put("/**","authc");
        factoryBean.setFilterChainDefinitionMap(map);

        //Set custom authentication filters
        HashMap<String,Filter> filterMap=new HashMap<String, Filter>();
        filterMap.put("authc",new LoginFilter());
        factoryBean.setFilters(filterMap);

        return factoryBean;
    }

    @Bean //register filter
    public FilterRegistrationBean<Filter> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

(3) Create service dao

service

@Service
public class UserService {
    @Autowired(required = false)
    private UserMapper userMapper;
    public User findByUsername(String username) {
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("username",username);
        User user=userMapper.selectOne(wrapper);
        return user;
    }

    public List<String> findPermissionByUsername(Integer userid) {
        List<String> list = userMapper.selectByUserId(userid);
        return list;
    }
}

dao

@Mapper
public interface UserMapper extends BaseMapper<User>{
    @Select(value = "select percode from user_role ur join role_permission rp on ur.roleid=rp.roleid join permission p on  rp.perid=p.perid where ur.userid=#{userid}")
    List<String> selectByUserId(Integer userid);
}

(4) Create realm

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

    //When to execute this method: This method will be executed when you perform permission verification
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        //Query which permissions the user has based on the account
        List<String> list= userService.findPermissionByUsername(user.getUserid());
        if(list!=null&&list.size()>0){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            info.addStringPermissions(list);
            return info;
        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1. Obtain an account according to the token
        String username = (String) authenticationToken.getPrincipal();
        //2. Query user information according to the account
        User user = userService.findByUsername(username);
        if(user!=null){
            //password obtained from the database
            ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUserpwd(),credentialsSalt,this.getName());
            return info;
        }
        return null;
    }
}

Turn on shiro annotations

 //start shiro annotation
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

shiroconfig configuration

package com.wk.config;


import com.wk.filter.LoginFilter;
import com.wk.realm.MyRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.HashMap;


@Configuration
public class ShiroConfig {


    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(realm());
        return securityManager;

    }

    @Bean
    public Realm realm(){
        MyRealm myRealm=new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

    @Bean(value = "shiroFilter")
    public ShiroFilterFactoryBean filterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());

        //Set blocking rules
        HashMap<String,String> map=new HashMap<>();
        map.put("/login","anon");
        map.put("/*.css","anon");
        map.put("/doc.html","anon");
        map.put("/v2/api-docs", "anon");
        map.put("/configuration/security", "anon");map.put("/swagger-resources", "anon");
        map.put("/configuration/ui", "anon");
        map.put("/**","authc");
        factoryBean.setFilterChainDefinitionMap(map);

        //Set custom authentication filters
        HashMap<String,Filter> filterMap=new HashMap<String, Filter>();
        filterMap.put("authc",new LoginFilter());
        factoryBean.setFilters(filterMap);

        return factoryBean;
    }

    @Bean //register filter
    public FilterRegistrationBean<Filter> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    //start shiro annotation
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}

 

Tags: Java Spring Boot security System Safety

Posted by earthlingzed on Thu, 15 Sep 2022 21:52:31 +0300