I am implementing Onelogin authentication for my React Spring boot application where User authentication is happening at frontend adn two tokens access_token and id_token are received.
As user details like username,email are only available in id_token not in access_token, it's being passed to Spring boot backend for verification and expiry like this:
@Configuration
public class JWTWebSecurityConfig extends WebSecurityConfigurerAdapter{
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("In JwtSecurityConfig");
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/swagger-ui/**",
"/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer().jwt();
}
}
Then In filter I am fetching the username and email from the id_token that is being passed in header like this:
@Component
public class JwtTokenAuthorizationOncePerRequestFilter extends OncePerRequestFilter {
@Value("${jwt.http.request.header}")
private String tokenHeader;
private static final Pattern BEARER_PATTERN =
Pattern.compile("^(?i:bearer) ([\\w\\x2b\\x2d\\x2e\\x2f\\x7e]+\\x3d*)$");
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
final String requestToken = request.getHeader(this.tokenHeader);
String email=null,name=null;
if(StringUtils.hasText(requestToken)) {
requestToken.replace("Bearer ","");
String[] chunks = requestToken.split("\\.");
Base64.Decoder decoder = Base64.getUrlDecoder();
String payload = new String(decoder.decode(chunks[1]));
ObjectMapper mapper = new ObjectMapper();
ObjectNode object = mapper.readValue(payload, ObjectNode.class);
email = object.get("email").asText();
name = object.get("name").asText();
if (email != null) {
request.setAttribute("user",email);
request.setAttribute("name",name);
}
}
chain.doFilter(request, response);
}
}
I am not sure if this is the correct approach for verification/validation of token and then passing the user details to controller.
I have tried using Principal Object injected into controller but it's not having the required user details in it.
@RequestMapping("/user")
public Principal user(Principal principal) {
System.out.println(principal);
return principal;
}
Please suggest if I am following the correct approach for OpenId Connect implementation with onelogin or there is better way to do it.
Regards,