I have web application which and i am trying to make keycloak
authorizations
on JavaScript side I am going on keycloak
login page and authenticating successfully. Here is my code
var keycloak = Keycloak({
realm: 'demo',
url: 'localhost:8080/auth',
clientId: 'justice'
});
keycloak.init({ onLoad: 'login-required' }).success(function(authenticated) {
alert(authenticated ? 'authenticated' : 'not authenticated');
}).error(function() {
alert('failed to initialize');
});
then I am calling Rest web service
on java
side
$.ajax({
type: "POST",
url: "login",
headers: {
"Authorization":"Bearer "+ keycloak.token
},
success: function (response) {
location.reload();
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
Here is everything okay, I am taking token and putting in header,But I have problem on java side, Can not take this authorization token
, user role
and some other properties
from this token
.
Here is my configuration
class which uses spring security config
import javax.servlet.http.HttpServletRequest;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory;
import org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.representations.AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy()).and().authorizeRequests()
.antMatchers("/login*").hasRole("ADMIN").anyRequest().permitAll();
}
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken getAccessToken() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
return ((KeycloakAuthenticationToken) request.getUserPrincipal()).getAccount().getKeycloakSecurityContext()
.getToken();
}
}
Then I am trying to take token but every try is useless.
I tried this way and result is null
@Controller
@RequestMapping
public class AuthController {
@Autowired
private AccessToken accessToken;
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {
//principal field is null
String token = accessToken.getAccessTokenHash(); // null
}
and this way
@Controller
@RequestMapping
public class AuthController {
@Autowired
private AccessToken accessToken;
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {
Authentication auth =SecurityContextHolder.getContext().getAuthentication();
KeycloakPrincipal principal = (KeycloakPrincipal) auth.getPrincipal(); // again null
}
and this way also
@Controller
@RequestMapping
public class AuthController {
@Autowired
private AccessToken accessToken;
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext(); // and still null
}
here is content of my keycloak.json
which is placed in WEB-INF
{
"realm": "demo",
"bearer-only": true,
"auth-server-url": "localhost:8080/auth",
"ssl-required": "external",
"resource": "justice-service",
"use-resource-role-mappings": true
}
Maybe I misunderstand flow of this authentication
or something.Maybe I have some mistakes in code or in configuration
. I just need to take token
and properties
from this token i.e. user role or username on java side. I am using first time keycloak authentication
, anyway do I need to set this Adapters
on JavaScript
and on Java
side too like I have ? Or is it enough to have only in JavaScript
?
from Can not get keycloak authorization token in spring
No comments:
Post a Comment