Search code examples
javaspring-bootoauth-2.0token

How can I bypass the Oauth2 authentication with predefined tokens in Spring Boot?


In Spring Boot project, I want to bypass authentication for some "magic" tokens. For example, I get a request header parameter as Authorization:Bearer abcdef-xyz. If this is not a valid access token, I'll check my predefined tokens. If one of them is matched, I will create a dummy user for the Security Context, and allow the request to proceed.


Solution

  • I've found a way to implement this.

    • Override readAccessToken method on InMemoryTokenStore
    • Check the token value according to your needs
    • If the token fits your pattern, get related info from token and validate
    • If it is validated then you can create a dummy authentication and call storeAccessToken method

      public OAuth2AccessToken readAccessToken(String tokenValue) {
      Pattern pattern = Pattern.compile(HRN_REGEX);
      Matcher matcher = pattern.matcher(tokenValue);
      OAuth2AccessToken oAuth2AccessToken = super.readAccessToken(tokenValue);
      if (oAuth2AccessToken == null && matcher.find()) {
          String group = matcher.group();
          String companyStr = group.replace(LICENCE_TOKEN_PREFIX, "");
          Long companyId= Long.valueOf(companyStr);
          boolean isCompanyValid = mLoginUserService.validateCompanyIdForAnonymousLogin(companyId);
          if (isCompanyValid) {
              OAuth2Request storedReq = new OAuth2Request(generateDummyReqParameters(), CLIENT, null, true, generateScope(), generateResourceIds(), null, null, null);
              Authentication userAuth = new AnonymousAuthenticationToken(companyStr, companyId, AuthorityUtils.createAuthorityList(ROLE_COMPANY));
              OAuth2Authentication authentication = new OAuth2Authentication(storedReq, userAuth);
              storeAccessToken(new DefaultOAuth2AccessToken(tokenValue), authentication);
              return new DefaultOAuth2AccessToken(tokenValue);
          } else {
              throw new InvalidTokenException(COMPANY_IS_NOT_LICENCED);
          }
      }
      return oAuth2AccessToken;}
      
    • Give a role to this authentication ("ROLE_COMPANY" in my case)

    • In your ResourceServerConfigurerAdapter class override configure(HttpSecurity http) method and give this role to related endpoints

      public void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
              .antMatchers("/tools/validate/**").hasAnyAuthority(ROLE_COMPANY, ROLE_USER, ROLE_ADMIN)
              .anyRequest().hasAnyAuthority(ROLE_USER, ROLE_ADMIN);    }