Thanks to visit codestin.com
Credit goes to github.com

Skip to content

maurofokker/spring-microservices-oauth-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring Microservice Oauth authorization server

Config Authorization Server

  • Add @EnableAuthorizationServer annotation
    • will support with a number of defaults for the oauth authorization server
    • will expose a number of endpoints that can be use to receive, validate or refresh a token
  • Create a configuration class (AuthorizationServerConfig.java) that extends AuthorizationServerConfigurerAdapter that is going to facilitate the configuration of the project
    • add @Configuration annotation to new class so spring's IoC container will pick up this class and begin building beans
    • inject an AuthenticationManager because this demo is using password grant that is not enabled by default within Spring Cloud support for Oauth
    • override configure(AuthorizationServerEndpointsConfigurer endpoints) method and inject AuthenticationManager bean
      @Override
          public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
              endpoints.authenticationManager(authenticationManager);
          }
    • override configure(ClientDetailsServiceConfigurer clients) method that will allow to set up the oauth client that is need available within the application or within the authorization server (for this demo it will be in memory)
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          // establish a config for a web app client in the auth server config
          clients.inMemory()
                  .withClient("webapp")
                  .secret("{noop}secret")  // to avoid There is no PasswordEncoder mapped for the id \"null\"
                  .authorizedGrantTypes("password")       // it is how user authenticate with the auth server
                  .scopes("read,write,trust") // determine the access level to the different pieces of the API
      }
  • Create a web security config class (WebSecurityConfig.java) that extends WebSecurityConfigurerAdapter.class
      @Configuration
      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      
          @Bean
          public AuthenticationManager authenticationManagerBean() throws Exception {
              return super.authenticationManagerBean();
          }
      
          // allow to specify the user within the web application
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.inMemoryAuthentication()
                      .withUser("user1")
                      .password("{noop}password") // to avoid There is no PasswordEncoder mapped for the id \"null\"
                      .roles("USER")
                      ;
          }
      }
  • Test with Postman
    • POST method
    • URL: http://localhost:9090/oauth/token?grant_type=password&username=user1&password=password
      • QUERY STRING PARAMS: are according the oauth specification that denotes how we exchange the different calls between the different pieces of the architecture within oauth security in order for them to follow specific process to grant users access to some resource
        • grant_type: password (see AuthorizationServerConfig.java) - oauth2 spec
        • username
        • password
    • Authentication: Basic
      • username: webapp
      • password: secret
    • Expected response:
    {
        "access_token": "1355ede7-3a32-43df-9fb0-75883bab0636",
        "token_type": "bearer",
        "expires_in": 43199,
        "scope": "read,write,trust"
    }

Config Resource Server

  • NOTE resource server is implemented separated from authorization server here

  • is the underlaying API server that is used to access user information

  • using a token from the authorization server allow to obtain acces to protected resources located in the rest API

  • to have the authorization server and resource server configuration in the same place is only applicable for the most trivial of applications

  • in order to establish the resource server we need:

    • add @EnableResourceServer annotation
    • and must exist a resource that is going to be protected by the resource server i.e.
      @RequestMapping("/resource/endpoint")
      public String endpoint() {
      	return "resource protected by the resource server";
      }
    • @RestController allow to expose the resource API (with @RequestMapping) and act as part of the Resource Server which works in tandem with the Auhorization Server to protect the resource
  • Test

    • when hit direct to endpoint http://localhost:9090/resource/endpoint without access token the client receive a 401 Unauthorized
      {
          "error": "unauthorized",
          "error_description": "Full authentication is required to access this resource"
      }
    • in order to grant access to the resource a token must be created and give that token to the request of the endpoint
      1. hit authorization server to create token described above in this document (authorization server config)
      {
          "access_token": "a4c6f9fd-7bf7-4823-9649-d1116f82df8e",
          "token_type": "bearer",
          "expires_in": 43199,
          "scope": "read,write,trust"
      }
      1. hit resource endpoint with token created above http://localhost:9090/resource/endpoint?access_token=a4c6f9fd-7bf7-4823-9649-d1116f82df8e
      resource protected by the resource server
      
      • access_token: is accepted by the resource server due to the relationship with authorization server within the authentication scheme
  • Protect API endpoints with spring security method security annotations

    • add @EnableGlobalMethodSecurity annotation using the prePostEnabled set to true
    • add @PreAuthorize("hasRole('ADMIN')") method annotation to discerning who is able to invoke this method in the expression the user needs to have the ADMIN role to access this method
        @RequestMapping("/resource/endpoint")
        @PreAuthorize("hasRole('ADMIN')")
        public String endpoint() {
            return "resource protected by the resource server";
        }
    • to test this configuration create an access token for user admin and then access to the annotated method if token is created with user user then resource server will not grant access

Token management with JDBC

  • database will store information about tokens that were issued by the authorization server

  • resource server will use the database to confirm the tokens received are valid and were issued by the authorization server

  • this test is with an HSQLDB

    • download hsqldb
    • create server.properties in root directory of hsqldb
        server.database.0=file:hsqldb/poc
        server.dbname.0=testdb
        server.port=9137
    • build server from root directory of hsqldb
        $java -classpath lib/hsqldb.jar org.hsqldb.server.Server
      
    • start server
        $java -classpath lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:hsqldb/poc --dbname.0 testdb 
      
    • hsqldb GUI can be found in bin/runManagerSwing
      • select type: hsql database engine server and user port defined in server.properties
  • configure schema in spring boot creating src/main/resources/schema.sql

    • schema.sql is a special spring boot file name because it will pick the file and load any scripts within the file into the jdbc store (hsqldb) prior to starting the application
  • add configure(AuthorizationServerSecurityConfigurer security) in AuthorizationServerConfig file

  • set the data source bean for the hsqldb server

      @Bean
      public DataSource dataSource() {
          DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
          dataSource.setUrl("jdbc:hsqldb:hsql://localhost:9137/testdb");
          dataSource.setUsername("SA");
          dataSource.setPassword("");
          return dataSource;
      }
  • create a TokenStore object of type JdbcTokenStore injecting the data source bean

  • edit body of configure(ClientDetailsServiceConfigurer clients) method

      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          clients.jdbc(dataSource()); // to allow to connect to db and retrieve clients 
      }
  • reference:

Oauth client

  • Demo can be found here

About

microservices demo using spring boot cloud and outh2 auth server configuration

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages