Authentication and authorization of spring security oauth2.0

In addition to oauth and shiro, we learn oauth 2.0 here

1.1

Authentication and authorization are two basic concepts to solve software system security. Authentication is to verify whether the user's identity is legal, and authorization is to verify whether the user has the authority to operate resources. The development of Internet also promotes the progress of software open design. Software should be open and safe. How to use a unified solution to solve the authentication requirements of software itself and external systems is a problem to be considered in current Internet applications. OAuth2.0 protocol is the current open and popular authentication protocol. This course uses the popular spring The security authentication framework and OAuth2.0 protocol realize the authentication and authorization technology solutions of single and distributed systems.

1.2

What is certification

What is authorization

 

1.3 what is conversation

After the user passes the authentication, in order to avoid every operation of the user needing authentication, we put the user's login information in the drawing. The session is the mechanism provided by the system to ensure the user's login page status. The common methods are session based and token based

The difference between session and token:

a. session needs to put the data in the cookie. token does not need to be put in the cookie, but also in the localStorage

b. Based on the session, the server stores the session, while the token server does not need to store, but verifies whether the token sent by the client is correct

 

1.4 authorized data model

Authorization can be understood as who's how to operate what (which), i.e. what kind of resources and how to operate those users

 

 

1.5.1 how to authorize:

2. session based authentication method:

 

Here's the actual battle: first, you can write a session based authentication login to familiarize yourself with the process, and then you can use spring based security to authenticate and authorize

pom file

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xiaofeifei.security</groupId>
    <artifactId>security-springmvc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>securityspringmvc</finalName>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <port>9090</port>
                        <path>/</path>
                        <server>tomcat7</server>
                        <ignorePackaging>true</ignorePackaging>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>

                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>utf-8</encoding>
                        <useDefaultDelimiters>true</useDefaultDelimiters>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <filtering>true</filtering>
                                <includes>
                                    <include>**/*</include>
                                </includes>
                            </resource>
                            <resource>
                                <directory>src/main/java</directory>
                                <includes>
                                    <include>**/*.xml</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>


</project>

We use servlet 3.0, so many configurations are not configured in config. We directly configure them in java classes, and web.xml We all configure in java classes

Basic knowledge:

spring containers are applicationContext.xml

servletContext is springmvc.xml

Our configuration applicationContext.xml Corresponding class

package com.xiaofeifei.security.springmvc.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration  //amount to applicationContext.xml  , after servlet3.0, the configuration can be placed in the class
@ComponentScan(basePackages = "com.xiaofeifei.security.springmvc"
        ,excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)})
        //Configure other beans except Controller here, such as database link pool, transaction manager, business bean, etc. Configure springcontext here
        //controller will configure scan in servletcontext
public class ApplicationConfig {
}

Our configuration springmvc.xml Corresponding class

package com.xiaofeifei.security.springmvc.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration //This configuration is equivalent to springmvc.xml
@EnableWebMvc
@ComponentScan(basePackages = "com.xiaofeifei.security.springmvc"
        ,includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class)}) //Only packages with Controller annotation are scanned here, because other packages are scanned with ApplicationConfig package
public class WebConfig implements WebMvcConfigurer {

    //Configure view resolver
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/view/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    //Direct / direct login.jsp
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
    }
}

And then we need web.xml , implement ApplicationInitializer or inherit the subclass of this class, which is equivalent to web.xml

package com.xiaofeifei.security.springmvc.init;

import com.xiaofeifei.security.springmvc.config.ApplicationConfig;
import com.xiaofeifei.security.springmvc.config.WebConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

//A parent interface of the inherited class is WebApplicationInitializer, which is equivalent to web.xml Servlets and listener s configured in
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //The purpose of this method is to load the spring container, that is, load applicationContext.xml
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class};  //Configure container
    }

    //The function is to load servletContext, which is equivalent to loading springmvc.xml
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};    // Configure servlet
    }

    //The function is to load URL mapping
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};            //Configure the access path, here is the root path
    }
}

Create jsp page

 

Then click Run:

Error will be reported after startup. This lombok is compatible with tomcat7, but does not affect the effect

Define controller

package com.xiaofeifei.security.springmvc.controller;

import com.xiaofeifei.security.springmvc.model.AuthenticationRequest;
import com.xiaofeifei.security.springmvc.model.UserDto;
import com.xiaofeifei.security.springmvc.service.impl.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class LoginController {

    @Autowired
    private AuthenticationService authenticationService;

    @RequestMapping(value = "/login", produces = "text/plain;charset=utf-8") //The role of text/plain;charset=utf-8 is that high-speed browsers return text types
    public String login(AuthenticationRequest authenticationRequest, HttpSession session) {
        UserDto userDto = authenticationService.authentication(authenticationRequest);

        session.setAttribute(UserDto.SESSION_USER_KEY, userDto);

        return userDto.getUsername() + "Login successful";
    }

    @GetMapping(value = "/logout", produces = "text/plain;charset=utf-8")
    public String logout(HttpSession session) {
        session.invalidate();
        return "Exit successful";
    }

    @GetMapping(value = "r/r1", produces = "text/plain;charset=utf-8")
    public String r1(HttpSession session) {
        String fullname = null;
        Object object = session.getAttribute(UserDto.SESSION_USER_KEY);
        if (object == null) {
            fullname = "anonymous";
        }else {
            UserDto userDto = (UserDto) object;
            fullname = userDto.getFullname();
        }
        return fullname + "Access resources r1";
    }

    @GetMapping(value = "r/r2", produces = "text/plain;charset=utf-8")
    public String r2(HttpSession session) {
        String fullname = null;
        Object object = session.getAttribute(UserDto.SESSION_USER_KEY);
        if (object == null) {
            fullname = "anonymous";
        }else {
            UserDto userDto = (UserDto) object;
            fullname = userDto.getFullname();
        }
        return fullname + "Access resources r1";
    }
}

Define interceptor

package com.xiaofeifei.security.springmvc.interceptor;

import com.xiaofeifei.security.springmvc.model.UserDto;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
public class SimpleAuthenticationInterceptor implements HandlerInterceptor {


    @Override //We need to intercept before calling all controller
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //In this method, verify whether the url requested by the user is within the user's permission range
        Object object = request.getSession().getAttribute(UserDto.SESSION_USER_KEY);
        if (object == null) {
            writeContent(response, "Please log in");
        }

        UserDto userDto = (UserDto) object;

        String requestURI = request.getRequestURI();

        if (userDto.getAuthorities().contains("p1") && requestURI.contains("/r/r1"))  //Accessible / r/r1 with p1 permission
        {
            return true;
        }

        if (userDto.getAuthorities().contains("p2") && requestURI.contains("/r/r2"))  // Those with p2 permission can access / r/r2
        {
            return true;
        }

        writeContent(response, "No permission, access denied");

        return false;
    }

    //Response information to client
    private void writeContent(HttpServletResponse response, String message) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(message);
        writer.close();
    }
}

Define multiple entity classes

package com.xiaofeifei.security.springmvc.model;

import lombok.Data;

/**
 * Request authentication parameters: account and password
 */
@Data //Use the Data annotation of lombok plug-in, and then generate get and set methods when compiling
public class AuthenticationRequest {

    private String username;

    private String password;

}
package com.xiaofeifei.security.springmvc.model;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Set;

/**
 * User information plug-in
 */
@Data  //Use the Data annotation of lombok plug-in, and then generate get and set methods when compiling
@AllArgsConstructor //The function is to take all member variables as parameters of a constructor
public class UserDto {

    public static final String SESSION_USER_KEY = "_user";

    //User identity information
    private String id;
    private String username;
    private String password;
    private String fullname;
    private String mobile;

    /**
     * User rights
     */

    private Set<String> authorities;
}

 

 

The following is based on security:

The principle of spring security

 

The accessdecisionmanager class has three implementation classes with different voting rules

 

Using spring security to solve 403 problems

Among them, the way of stateless is to use token instead of session for authentication and authorization

Exit of spring security

 

Based on method interception, we usually intercept the controller, because the controller is a user-oriented interface

Distributed system:

The process is as follows: first, the client applies for authorization from the resource owner, gets the authorization (authorization code), then takes the authorization code to access the authentication service to apply for a token, the authentication service judges that the authorization code is correct, then returns the token, and then the client takes the token to access the user information,

Keywords: Session xml Maven Spring

Added by phpnwx on Sun, 21 Jun 2020 13:26:10 +0300