Home >Java >javaTutorial >Using OAuth2 authentication in Java API development

Using OAuth2 authentication in Java API development

王林
王林Original
2023-06-18 11:49:371494browse

In the development of Java API, authentication is an inevitable issue. OAuth2 is a popular authentication method that protects API resources by granting access. This article will introduce how to use OAuth2 for authentication in Java API development.

Introducing OAuth2

OAuth2 is an open standard for authorization that allows users to authorize third-party applications to access their server resources without having to share their credentials. The OAuth2 standard includes the following roles:

  • Resource Owner: the resource owner, that is, the user;
  • Resource Server: the resource server, the server that provides resources;
  • Client: Client, that is, a third-party application;
  • Authorization Server: Authorization server, used to issue access tokens.

The authorization process of OAuth2 includes the following steps:

  • Client sends an authorization request to the Authorization Server;
  • Authorization Server requests authorization from the Resource Owner;
  • After the Resource Owner authorizes, the Authorization Server sends the access token to the Client;
  • Client uses the access token to send a request to the Resource Server;
  • Resource Server verifies the access token and provides resources .

OAuth2 supports multiple authorization types, including authorization code mode, password mode, client mode, implicit authorization mode, etc. In Java API development, authorization code mode and password mode are usually used.

OAuth2 Authorization Code Mode

Authorization code mode is the most commonly used authorization type in OAuth2. It includes the following steps:

  • Client sends an authorization request to the Authorization Server, Including Client ID and redirection URI;
  • Authorization Server sends the login page to the Resource Owner, requiring the Resource Owner to log in and authorize;
  • After the Resource Owner authorizes, the Authorization Server sends the authorization code to the redirection URI ;
  • Client uses the authorization code to send a request to the Authorization Server, including Client ID and Client Secret;
  • Authorization Server verifies the Client ID and Client Secret, and if correct, issues an access token to the Client;
  • Client uses the access token to send a request to the Resource Server.

In Java API development, you can use the Spring Security OAuth2 framework to implement authorization code mode authentication.

First, you need to add the following dependencies in the pom.xml file:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

Then, add the following configuration in the Spring MVC configuration file:

<security:http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="authenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <security:intercept-url pattern="/oauth/token" access="isAuthenticated()" method="POST" />
    <security:anonymous enabled="false" />
    <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

<security:http pattern="/api/**" create-session="never"
    entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager"
    xmlns="http://www.springframework.org/schema/security">
    <security:anonymous enabled="false" />
    <security:intercept-url pattern="/api/**" access="ROLE_USER" />
    <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="spring-boot-oauth2" />
    <property name="typeName" value="Basic" />
</bean>

<bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="spring-boot-oauth2" />
    <property name="typeName" value="Bearer" />
</bean>

<bean id="oauthAccessDeniedHandler"
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<bean id="clientCredentialsTokenEndpointFilter"
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="resourceServerFilter"
    class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="accessDecisionManager"
    class="org.springframework.security.access.vote.UnanimousBased"
    xmlns="http://www.springframework.org/schema/beans">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <bean class="org.springframework.security.access.vote.RoleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

<security:authentication-manager id="authenticationManager">
    <security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>

<bean id="userDetailsService"
    class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="dataSource" />
</bean>

Among them, / oauth/token is the path used to obtain the access token, and /api/** is the path that requires authentication.

When using OAuth2RestTemplate to send a request, you need to obtain an access token first. The code is as follows:

OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(client, context);
AuthorizationCodeResourceDetails details = (AuthorizationCodeResourceDetails)client.getResource();
AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider();
Authentication auth = new UsernamePasswordAuthenticationToken(username, password);
AccessTokenRequest tokenRequest = provider.createAccessTokenRequest(details, auth);
OAuth2AccessToken accessToken = provider.obtainAccessToken(details, tokenRequest);
restTemplate.getOAuth2ClientContext().setAccessToken(accessToken);

Among them, client is an object of type OAuth2ProtectedResourceDetails, containing information such as Client ID and Client Secret.

OAuth2 Password Mode

Password mode is an authorization type in OAuth2 suitable for trusting clients. It contains the following steps:

  • Client sends a request to the Authorization Server, including Client ID, Client Secret and Resource Owner's username and password;
  • Authorization Server verifies the Client ID, Client Secret and username and password, and if correct, issues an access token to the Client;
  • Client uses The access token sends a request to the Resource Server.

In Java API development, you can use the Spring Security OAuth2 framework to implement password mode authentication.

First, you need to add the following dependencies in the pom.xml file:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

Then, add the following configuration in the Spring MVC configuration file:

<security:http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="authenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <security:intercept-url pattern="/oauth/token" access="isAuthenticated()" method="POST" />
    <security:anonymous enabled="false" />
    <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

<security:http pattern="/api/**" create-session="never"
    entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager"
    xmlns="http://www.springframework.org/schema/security">
    <security:anonymous enabled="false" />
    <security:intercept-url pattern="/api/**" access="ROLE_USER" />
    <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="spring-boot-oauth2" />
    <property name="typeName" value="Basic" />
</bean>

<bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="spring-boot-oauth2" />
    <property name="typeName" value="Bearer" />
</bean>

<bean id="oauthAccessDeniedHandler"
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<bean id="clientCredentialsTokenEndpointFilter"
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="resourceServerFilter"
    class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="accessDecisionManager"
    class="org.springframework.security.access.vote.UnanimousBased"
    xmlns="http://www.springframework.org/schema/beans">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <bean class="org.springframework.security.access.vote.RoleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

<security:authentication-manager id="authenticationManager">
    <security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>

<bean id="userDetailsService"
    class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="dataSource" />
</bean>

Among them, / oauth/token is the path used to obtain the access token, and /api/** is the path that requires authentication.

When using OAuth2RestTemplate to send a request, you need to obtain the access token first. The code is as follows:

OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(details, new DefaultOAuth2ClientContext());
restTemplate.getOAuth2ClientContext().setAccessToken(accesstoken);

Among them, details is an object of ResourceOwnerPasswordResourceDetails type, including Client ID, Client Secret, user name and password, etc. .

Summary

Using OAuth2 for authentication in Java API development can protect the security of API resources and make it easier for users to authorize third-party applications to access their server resources. This article introduces the authorization code mode and password mode of OAuth2, and provides sample code for implementing authentication using the Spring Security OAuth2 framework. Hope it can be helpful to Java API developers.

The above is the detailed content of Using OAuth2 authentication in Java API development. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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