Home  >  Article  >  Java  >  How SpringBoot implements QR code scanning login

How SpringBoot implements QR code scanning login

PHPz
PHPzforward
2023-05-10 20:25:111595browse

1. The principle of scanning QR code to log in with mobile phone

Scanning QR code to log in is an authorized login method based on the OAuth3.0 protocol. In this way, the application does not need to obtain the user's username and password, only the user's authorization. There are mainly the following steps to log in by scanning the QR code:

  • The application generates a QR code and displays the QR code to the user.

  • Users use the code scanning tool to scan the QR code and authorize on the authorization page.

  • After the user authorizes the application, the application will obtain an authorization code.

  • The application uses this authorization code to request an access token from the authorization server.

  • The authorization server returns an access token to the application.

  • The application uses this access token to access the resource server.

How SpringBoot implements QR code scanning login

#Through the above steps, scanning the QR code to log in can realize the user’s quick login and ensure the user’s security and privacy.

2. How SpringBoot implements QR code scanning login

In SpringBoot, Spring Security OAuth3.0 can be used to implement the QR code scanning login function. Spring Security OAuth3.0 is a security framework based on the OAuth3.0 protocol, which provides the implementation of authorization server and resource server. Next, I will introduce to you how to use Spring Security OAuth3.0 to implement QR code scanning login.

Add dependencies
First, you need to add the dependency of Spring Security OAuth3.0 in the pom.xml file:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth3</artifactId>
    <version>2.4.0</version>
</dependency>

Configure the authorization server
In SpringBoot, you can pass @Configuration annotations to configure the authorization server. The following is a simple authorization server configuration example:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client")
                .secret("{noop}secret")
                .authorizedGrantTypes("authorization_code")
                .scopes("read", "write")
                .redirectUris("http://localhost:8080/callback");
    }

    @Override
    public void configure(AuthorizationServerEndpoints endpoints) throws Exception {
    endpoints.authenticationManager(authenticationManager);
}
}

In the above code, use the @EnableAuthorizationServer annotation to enable the authorization server. Then, specify the class as a configuration class through the @Configuration annotation. In the configure() method, an authorization client is configured and the authorization type is specified as authorization_code. The authorization server uses the inMemory() method to specify client information, including client ID, client key, authorization type, authorization scope, redirect address and other information. In the configure() method, you also need to configure the AuthenticationManager to verify the user's identity information.

Configuring the resource server

In SpringBoot, the resource server can be configured through the @Configuration annotation. The following is a simple resource server configuration example:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  @Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .anyRequest().permitAll();
}

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId("resource");
}
}

In the above code, use the @EnableResourceServer annotation to enable the resource server. Then, specify the class as a configuration class through the @Configuration annotation. In the configure() method, the security policy of the resource server is configured, the antMatchers() method is used to specify the interfaces that require authentication, and the permitAll() method is used to specify that other interfaces can be accessed anonymously. In the configure() method, you also need to configure the resource ID of the resource server.

Configuring the client

In SpringBoot, the client can be configured through the configuration file. The following is a simple client configuration example:

security:
oauth3:
client:
clientId: client
clientSecret: secret
accessTokenUri: http://localhost:8080/oauth/token
userAuthorizationUri: http://localhost:8080/oauth/authorize
scope: read,write
redirectUri: http://localhost:8080/callback

In the above code, the client configuration information is specified through the security.oauth3.client prefix, including client ID, client key, and access token. URI, user authorization URI, authorization scope, redirect address and other information.

Generate QR code

In SpringBoot, you can use a third-party library to generate QR code. The following is a simple QR code generation example:

@GetMapping("/qrcode")
public ResponseEntity<byte[]> getQRCode() throws IOException, WriterException {
String codeUrl = "http://localhost:8080/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8080/callback";
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 200, 200);
MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);
return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(outputStream.toByteArray());
}

In the above code, use the @GetMapping annotation to specify the method as a GET request processing method, and map the method by specifying the request path "/qrcode" method. In the getQRCode() method, first generate the URL of the authorization request, and use a third-party library to generate a QR code image. Finally, the generated QR code image is returned to the client in the form of a byte array.

Scan code login
In SpringBoot, WebSocket can be used to implement the scan code login function. The following is a simple QR code login example:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new QRCodeHandler(), "/qrcodeHandler");
    }

    class QRCodeHandler extends TextWebSocketHandler {

        private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

        @Override
        public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            String token = message.getPayload();
            if (sessions.containsKey(token)) {
                WebSocketSession clientSession = sessions.get(token);
                clientSession.sendMessage(new TextMessage("authenticated"));
                session.sendMessage(new TextMessage("authenticated"));
            } else {
                sessions.put(token, session);
            }
        }

        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            sessions.values().remove(session);
        }
    }
}

In the above code, use the @EnableWebSocket annotation to enable WebSocket support. Then, specify the class as a configuration class through the @Configuration annotation. In the registerWebSocketHandlers() method, a WebSocket processor is registered and the request path of the processor is specified. In the QRCodeHandler class, the business logic of the WebSocket processor is implemented. In the handleTextMessage() method, use the token generated after scanning the QR code as the key and save the WebSocket session object in the Map. If the WebSocket session object corresponding to the same token already exists, it means that the user has scanned the code and passed the authentication. At this time, the two WebSocket session objects need to notify each other that the authentication has passed. If the WebSocket session object corresponding to the same token does not exist, the WebSocket session object is saved in the Map. In the afterConnectionClosed() method, remove the closed WebSocket session object.

Client callback
In SpringBoot, you can use the @Controller annotation to implement the client's callback function. Here is a simple callback example:

@Controller
public class CallbackController {

    @Autowired
    private OAuth3RestTemplate restTemplate;

    @GetMapping("/callback")
    public String callback(@RequestParam("code") String code) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", "authorization_code");
        params.add("code", code);
        params.add("redirect_uri", "http://localhost:8080/callback");
        params.add("client_id", "client");
        params.add("client_secret", "secret");
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        OAuth3AccessToken token = restTemplate.postForObject("http://localhost:8080/oauth/token", request, OAuth3AccessToken.class);
        return "redirect:/home";
    }
}

在上面的代码中,使用@Controller注解来指定该类为一个控制器。在callback()方法中,首先使用OAuth3RestTemplate来发送POST请求获取访问令牌,并将授权码、回调URL、客户端ID和客户端秘钥等参数作为请求体发送。在获取到访问令牌之后,重定向到应用程序的主页。

The above is the detailed content of How SpringBoot implements QR code scanning login. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete