Table of Contents
Preparation
Effect display
Home Java javaTutorial How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

May 11, 2023 am 10:28 AM
spring springboot security

Preparation

spring-boot: 2.1.4.RELEASE

spring-security-oauth3: 2.3.3.RELEASE (If you want to use the source code, do not change this version number at will, because The writing method from 2.4 up is different)

mysql: 5.7

Effect display

Only postman is used for testing here, and the front-end page is not used for docking yet. Next There will be a page display for the permission allocation of the version role menu

1. Access the open interface http://localhost:7000/open/hello

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

2 . Access the protected interface http://localhost:7000/admin/user/info

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

## without a token. 3. Obtain the token after logging in, bring the token to access, and return successfully. The current login user information

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

realize

oauth3 has four modes in total, which will not be explained here. Yes, I searched online and found the same thing

Because now we only consider unilateral applications, we use the password mode.

There will be an article on SpringCloud Oauth3 later, gateway authentication

Let’s talk about a few points

1. Interceptor configuration dynamic permissions

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

Create a new MySecurityFilter class, inherit AbstractSecurityInterceptor, and implement the Filter interface

Initialization, custom access decision manager

@PostConstruct
 public void init(){
        super.setAuthenticationManager(authenticationManager);
        super.setAccessDecisionManager(myAccessDecisionManager);
  }
Copy after login

Custom filter calls security metadata Source

@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
    return this.mySecurityMetadataSource;
}
Copy after login

Let’s first look at the core code of the custom filter calling the secure metadata source

The following code is used to obtain the permissions (roles) required for the current request to come in

/**
     * 获得当前请求所需要的角色
     * @param object
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) object).getRequestUrl();

        if (IS_CHANGE_SECURITY) {
            loadResourceDefine();
        }
        if (requestUrl.indexOf("?") > -1) {
            requestUrl = requestUrl.substring(0, requestUrl.indexOf("?"));
        }
        UrlPathMatcher matcher = new UrlPathMatcher();
        List<Object> list = new ArrayList<>();  //无需权限的,直接返回
        list.add("/oauth/**");
        list.add("/open/**");
        if(matcher.pathsMatchesUrl(list,requestUrl))
            return null;

        Set<String> roleNames = new HashSet();
        for (Resc resc: resources) {
            String rescUrl = resc.getResc_url();
            if (matcher.pathMatchesUrl(rescUrl, requestUrl)) {
                if(resc.getParent_resc_id() != null && resc.getParent_resc_id().intValue() == 1){   //默认权限的则只要登录了,无需权限匹配都可访问
                    roleNames = new HashSet();
                    break;
                }
                Map map = new HashMap();
                map.put("resc_id", resc.getResc_id());
                // 获取能访问该资源的所有权限(角色)
                List<RoleRescDTO> roles = roleRescMapper.findAll(map);
                for (RoleRescDTO rr : roles)
                    roleNames.add(rr.getRole_name());
            }
        }

        Set<ConfigAttribute> configAttributes = new HashSet();
        for(String roleName:roleNames)
            configAttributes.add(new SecurityConfig(roleName));

        log.debug("【所需的权限(角色)】:" + configAttributes);

        return configAttributes;
    }
Copy after login

Let’s take a look at the core code of the custom access decision manager. This code is mainly used to determine whether the currently logged in user (the role owned by the currently logged in user will be written in the last item) has the permission role

@Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        if(configAttributes == null){   //属于白名单的,不需要权限
            return;
        }
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while (iterator.hasNext()){
            ConfigAttribute configAttribute = iterator.next();
            String needPermission = configAttribute.getAttribute();
            for (GrantedAuthority ga: authentication.getAuthorities()) {
                if(needPermission.equals(ga.getAuthority())){   //有权限,可访问
                    return;
                }
            }
        }
        throw new AccessDeniedException("没有权限访问");

    }
Copy after login

2. Customize authentication exceptions to return common results

Why is this needed? If this is not configured, it will be difficult for the front end and the back end to understand the content returned by the authentication failure. It is not possible yet. Unified interpretation, without further ado, let’s first look at the return situation without configuration and configuration

(1) Before customization, when accessing the protected API interface without a token, the returned result is as follows ’s

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

# (2) Let’s stipulate that after the interface that fails to authenticate returns to the interface, it will become the following. Is it better for us to process and prompt the user

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

Okay, let’s take a look at where to configure it

Our resource server OautyResourceConfig, rewrite the following part of the code to customize the authentication The result returned by the exception

You can refer to this https://www.yisu.com/article/131668.htm

@Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.authenticationEntryPoint(authenticationEntryPoint)    //token失效或没携带token时
                .accessDeniedHandler(requestAccessDeniedHandler);   //权限不足时
    }
Copy after login

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

3. Get the current Login user

First method: Use JWT to carry user information, and then parse after getting the token

No explanation for now

Second method: Write a SecurityUser to implement the UserDetails interface (This is the one used in this project)

The original only UserDetails interface only has username and password. Here we add the User in our system

protected User user;
    public SecurityUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }
Copy after login

In BaseController, each Controller will Inheriting this, we write the getUser() method in it. As long as the user brings a token to access, we can directly obtain the information of the currently logged in user.

protected User getUser() {
        try {
            SecurityUser userDetails = (SecurityUser) SecurityContextHolder.getContext().getAuthentication()
                    .getPrincipal();

            User user = userDetails.getUser();
            log.debug("【用户:】:" + user);

            return user;
        } catch (Exception e) {
        }
        return null;
    }
Copy after login

So after the user logs in successfully, how to get the user The role collection, etc., here we need to implement the UserDetailsService interface

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

@Service
public class TokenUserDetailsService implements UserDetailsService{

    @Autowired
    private LoginService loginService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = loginService.loadUserByUsername(username);  //这个我们拎出来处理
        if(Objects.isNull(user))
            throw new UsernameNotFoundException("用户名不存在");
        return new SecurityUser(user);
    }
}
Copy after login

Then set the UserDetailsService in our security configuration class to the one we wrote above

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
Copy after login

Finally we only need to implement our method in loginService, and judge whether the user exists based on our actual business processing, etc.

@Override
    public User loadUserByUsername(String username){
        log.debug(username);
        Map map = new HashMap();
        map.put("username",username);
        map.put("is_deleted",-1);
        User user = userMapper.findByUsername(map);
        if(user != null){
            map = new HashMap();
            map.put("user_id",user.getUser_id());
            //查询用户的角色
            List<UserRoleDTO> userRoles = userRoleMapper.findAll(map);
            user.setRoles(listRoles(userRoles));
            //权限集合
            Collection<? extends GrantedAuthority> authorities = merge(userRoles);
            user.setAuthorities(authorities);
            return user;
        }
        return null;

    }
Copy after login

The database file is in this

How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?

The above is the detailed content of How does SpringBoot integrate SpringSecurityOauth2 to implement dynamic permission issues for authentication?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

17 ways to solve the kernel_security_check_failure blue screen 17 ways to solve the kernel_security_check_failure blue screen Feb 12, 2024 pm 08:51 PM

Kernelsecuritycheckfailure (kernel check failure) is a relatively common type of stop code. However, no matter what the reason is, the blue screen error causes many users to be very distressed. Let this site carefully introduce 17 types to users. Solution. 17 solutions to kernel_security_check_failure blue screen Method 1: Remove all external devices When any external device you are using is incompatible with your version of Windows, the Kernelsecuritycheckfailure blue screen error may occur. To do this, you need to unplug all external devices before trying to restart your computer.

A new programming paradigm, when Spring Boot meets OpenAI A new programming paradigm, when Spring Boot meets OpenAI Feb 01, 2024 pm 09:18 PM

In 2023, AI technology has become a hot topic and has a huge impact on various industries, especially in the programming field. People are increasingly aware of the importance of AI technology, and the Spring community is no exception. With the continuous advancement of GenAI (General Artificial Intelligence) technology, it has become crucial and urgent to simplify the creation of applications with AI functions. Against this background, "SpringAI" emerged, aiming to simplify the process of developing AI functional applications, making it simple and intuitive and avoiding unnecessary complexity. Through "SpringAI", developers can more easily build applications with AI functions, making them easier to use and operate.

Use Spring Boot and Spring AI to build generative artificial intelligence applications Use Spring Boot and Spring AI to build generative artificial intelligence applications Apr 28, 2024 am 11:46 AM

As an industry leader, Spring+AI provides leading solutions for various industries through its powerful, flexible API and advanced functions. In this topic, we will delve into the application examples of Spring+AI in various fields. Each case will show how Spring+AI meets specific needs, achieves goals, and extends these LESSONSLEARNED to a wider range of applications. I hope this topic can inspire you to understand and utilize the infinite possibilities of Spring+AI more deeply. The Spring framework has a history of more than 20 years in the field of software development, and it has been 10 years since the Spring Boot 1.0 version was released. Now, no one can dispute that Spring

What are the implementation methods of spring programmatic transactions? What are the implementation methods of spring programmatic transactions? Jan 08, 2024 am 10:23 AM

How to implement spring programmatic transactions: 1. Use TransactionTemplate; 2. Use TransactionCallback and TransactionCallbackWithoutResult; 3. Use Transactional annotations; 4. Use TransactionTemplate in combination with @Transactional; 5. Customize the transaction manager.

Comparison and difference analysis between SpringBoot and SpringMVC Comparison and difference analysis between SpringBoot and SpringMVC Dec 29, 2023 am 11:02 AM

SpringBoot and SpringMVC are both commonly used frameworks in Java development, but there are some obvious differences between them. This article will explore the features and uses of these two frameworks and compare their differences. First, let's learn about SpringBoot. SpringBoot was developed by the Pivotal team to simplify the creation and deployment of applications based on the Spring framework. It provides a fast, lightweight way to build stand-alone, executable

How to set transaction isolation level in Spring How to set transaction isolation level in Spring Jan 26, 2024 pm 05:38 PM

How to set the transaction isolation level in Spring: 1. Use the @Transactional annotation; 2. Set it in the Spring configuration file; 3. Use PlatformTransactionManager; 4. Set it in the Java configuration class. Detailed introduction: 1. Use the @Transactional annotation, add the @Transactional annotation to the class or method that requires transaction management, and set the isolation level in the attribute; 2. In the Spring configuration file, etc.

Spring Annotation Revealed: Analysis of Common Annotations Spring Annotation Revealed: Analysis of Common Annotations Dec 30, 2023 am 11:28 AM

Spring is an open source framework that provides many annotations to simplify and enhance Java development. This article will explain commonly used Spring annotations in detail and provide specific code examples. @Autowired: Autowired @Autowired annotation can be used to automatically wire beans in the Spring container. When we use the @Autowired annotation where dependencies are required, Spring will find matching beans in the container and automatically inject them. The sample code is as follows: @Auto

Detailed explanation of Bean acquisition methods in Spring Detailed explanation of Bean acquisition methods in Spring Dec 30, 2023 am 08:49 AM

Detailed explanation of the Bean acquisition method in Spring In the Spring framework, Bean acquisition is a very important part. In applications, we often need to use dependency injection or dynamically obtain instances of beans. This article will introduce in detail how to obtain beans in Spring and give specific code examples. Obtaining the Bean@Component annotation through the @Component annotation is one of the commonly used annotations in the Spring framework. We can do this by adding @Compone on the class

See all articles