I am writing a small app with a spring boot rest based backend and a polymer dart based frontend.
Currently I'm struggling to receive the session id from the login mechanism...
Initially I planned to use the HeaderHttpSessionStrategy
and use this to authenticate against the spring-session/redis session store to enable horizontal scaling.
The problem is that spring security always performs a redirect after login and in dart the HttpRequest
class (from html package) and after the redirect the header field from the initial response is of course no longer present/accessible.
I tried to disable followRedirect for the client, but it looks like this is only available for the IO package HttpRequest
.
Then I tried to switch to CookieHttpSessionStrategy
but it looks like the dart httprequest does not store received cookies in the browsers cookie backend :-/
This should be a simple problem, but I'm a little bit lost here. This can't be that hard...
When I use for example the intellij rest client everything works and I can extract the session id from either the cookie or the header field...
Any ideas? :-/
It looks like dart always follows these redirects in the browser and I have no chance to retrieve the cookie or the token in the header of the first request.
So as alternative solution I'm trying to do this next:
Activate basic auth in spring security:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/logout").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.sessionManagement().sessionFixation().changeSessionId()
.and()
.csrf().disable();
}
...
}
In one controller I have something like this as a protected resource:
@RequestMapping(value = "login", method = RequestMethod.POST)
public String login() {
return RequestContextHolder.currentRequestAttributes().getSessionId();
}
This way you can get your session id as regular result. So I can simply fetch the ID from the response body and use it after I provide the correct basic auth credentials once.
This should only be used in trusted enviromnents or via https to make it harder for bad guys to sniff the credentials or session.
So basically this is what I do to log in:
void login() {
Map<String, String> headers = {};
authorize(headers);
HttpRequest.request(LOGIN_URL, method: "POST", requestHeaders: headers)
.then((request) => processLogin(request))
.catchError((e) => processLoginError(e));
}
void processLogin(HttpRequest request) {
sessionController.sessionId=request.responseText;
mainApp.showHome();
}
void processLoginError(var e) {
print("total failure to login because of $e");
}
String authorization() {
String auth = window.btoa("$username:$password");
return "Basic $auth";
}
void authorize(Map<String, String> headers) {
headers.putIfAbsent("Authorization", () => authorization());
}
To send requests with HeaderHttpSessionStrategy
I can do this:
void updateUserData(){
_logger.info("Updating user data");
Map<String, String> headers = {"Accept": "application/json", 'x-auth-token':sessionId};
HttpRequest.request(USER_URL, method: "GET", requestHeaders: headers)
.then((request) => processUserData(request))
.catchError(ErrorHandler.handleHttpErrorGeneric);
}
You could also get it to work with cookies, but I like the HttpRequest.request()
so it was easier to go with header fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With