we're having a JHipster-based API Gateway application which currently uses JJWT for .. I don't even know how to name it properly.. for security?
We're having an issue that we need to authenticate our user in a 3rd party service whenever it requests some operation against that 3rd party. So the idea is to use #SessionScope-d bean to keep user credentials in the 3rd party. Is it going to work? I am confused that JWT is said to be stateless.. What approach should the community propose then ? thanks
This is what has been investigated by my colleague:
To support #SessionScope annotation functionality for our gateway (UI - backend) firstly we should adjust some configuration:
In the application.yml we should change http-only session parameter to false:
server:
servlet:
session:
cookie:
http-only: false
Then we should configure session timeout to correlate it with our JWT token lifetime:
server:
servlet:
session:
timeout: 86400
Finally we should configure session creation policy. This can be done in the
SecurityConfiguration.java:
#Override public void configure(HttpSecurity http) throws Exception { http.sessionCreationPolicy(SessionCreationPolicy.ALWAYS); }
From this point we will have session which will store Spring Secuirty context for each authenticated user but it will never be used for authenticate mechanism as we already have JWT for that purpose. We will use session only for storing custom data.
After configuration we can now create custom bean for session scope:
CustomSessionScopeBean.java:
#Component
#SessionScope
public class CustomSessionScopeBean{
#Getter
#Setter
///What ever you want to store in session scope
}
Related
I have a Spring boot application with Spring Authorization Server (the new 4.0.1 package Spring Authorization)
The server is in a cluster of servers thus it needs to save the session in a DB so I use #EnableJdbcHttpSession.
The Authorization service has state change request (e.g login etc...) with HTTP POST called from client written in Angular JS.
In order to secure my HTTP POST requests I use csrf e.g. csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
Its seems that #EnableJdbcHttpSession invoke the HttpSessionCsrfTokenRepository so I can't define the post request to work with CookieCsrfTokenRepository.
When I define CookieCsrfTokenRepository the SESSION cookie is not getting created, is it possible to define both somehow ?
#Configuration
#EnableJdbcHttpSession
public class SecurityConfiguration {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize ->
authorize.anyRequest().authenticated()
).formLogin(withDefaults())
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
return http.build();
}
}
This code will fix the issue
http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS))
I am currently use AspNetBoilerplate to implement my services in service layer...
So I can access session in MVC controller like:
Token token = HttpContext.Session["Token"] as Token;
After login Token session be initiated....
I can access thta everywhere in MVC controllers but in ApplicationServiceBase it is null like:
public class AuditAppService : ApplicationServiceBase, IAuditAppService
{
public GetUserActions_Box GetUserActions()
{
var token = HttpContext.Current.Session.GetToken();
return GetUserActions_Box.Empty;
}
}
HttpContext.Current.Session is null why?
that app services are implemented in separate library which is added in main web application.
I followed the documentation and crossed This, I think AbpSession is not my solution which mean by it we can access some basics info about session that initiated by AbpBoilerPlate authentication system not ours.
use IAbpSession .
you can use claims to add your custom values to the AbpSession.
previously answered here about how to extend AbpSession
Extend ClaimsAbpSession
read AbpSession https://aspnetboilerplate.com/Pages/Documents/Abp-Session
I'm working on implementing SpringSession on an application with SpringSecurity using xml configuration. I followed this guide and the application is working 95%, confirmed that it is hitting the redis backend: http://docs.spring.io/spring-session/docs/current/reference/html5/guides/security.html
The application stores some information in a custom authentication token that extends UsernamePasswordAuthenticationToken. After implementing spring session, it seems like the data stored in the token is going to the wrong place or not persisting. The flow is like this:
Request is made and mapped to the Controller
The Controller gets the AuthorenticationToken in a fashion like this SecurityContextHolder.getContext().getAuthentication()
This token is the custom token that extends UsernamePasswordAuthenticationToken and a custom field is set like token.setFoo("bar")
The controller is finished and returns a ModelAndView with a redirect command like this redirect:/nextController
In the logs I see after the controller is finished, Chain processed normally and SecurityContextHolder now cleared and later, Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT
At this point, the field that I set in the auth token inside the SecurityContext, token.setFoo("bar"), is null.
If I disable the SpringSession configuration I can see that application uses a cookie called JSESSIONID instead of a cookie called SESSION and that the authentication token is populated and persists correctly.
Any help on this very troublesome bug would be greatly appreciated, thanks!
I've got a client app configured with #EnableOAuth2Sso and #EnableZuulProxy, and a resource server (separate app) configured with #EnableOAuth2Resource. I can see that the client correctly authenticates to the resource server with Authorization: Bearer {access_token here}, but when once the access token expires, the proxied resource server request fails permanently.
[Edited]
I've modified my resource server by providing a custom RemoteTokenServices bean that uses OpenAM's /tokeninfo endpoint to decide whether an access_token remains valid. (The Spring-provided RemoteTokenServices bean attempts to POST, which gets a 405 from OpenAM). When I detect the access_token is invalid, I throw InvalidTokenException from my.spring.oauth2.OpenAMRemoteTokenServices#loadAuthentication. Now, my resource server is (I think correctly) sending HTTP 401 on the response to the client, in the case where the access_token has expired.
Still, the client is not attempting to refresh the token.
Maybe my mental model is wrong. I expect the client, in the case of expired access_token, to automatically use the refresh_token to obtain a new one. I don't know whether I think it should proactively refresh an access_token (within some epsilon before expiry time), or wait for a downstream request to fail and try refreshing then. But my client appears to be doing neither, and I can't tell why not.
As stated in this git issue: https://github.com/spring-guides/tut-spring-security-and-angular-js/issues/140, the problem might be related to the fact that with versions 1.4 and above of spring boot the Zuul filter that handles the downstream of access tokens to services (org.springframework.cloud.security.oauth2.proxy.OAuth2TokenRelayFilter) is missing a bean of type OAuth2RestTemplate, which is used by the filter itself to automatically handle the refresh_token grant when access tokens expire.
I had the same issue and I solved it by adding in a configuration class the following bean:
#Configuration
public class ZuulConfiguration {
#Bean
protected OAuth2RestTemplate oauth2RestTemplate(OAuth2ProtectedResourceDetails resource,
OAuth2ClientContext context) {
return new OAuth2RestTemplate(resource, context);
}
}
I'm looking for some guidance on how to implement authorization security for SignalR on a back end service running in a self-hosted (non-IIS) environment, that is called from a Web application. The backend app is basically a monitor that fires SignalR events back to the HTML based client. This all works fine (amazingly well actually).
However, we need to restrict access to the server for authenticated users from the Web site. So basically if a user is authenticated on the Web site, we need to somehow pick up the crendentials (user name is enough) and validation state in the backend app to decide whether to allow the connection as to avoid unauthorized access.
Can anybody point at some strategies or patterns on how to accomplish this sort of auth forwarding?
I am having similar issues here, as in my web app I use a simple cookie authentication system which uses an AoP style approach to check for any controllers with an attribute, then will get the current context (be it from the static HttpContext.Current or from the target invocation object depending on the type of interceptor) and then verify the cookie exists, it contains right data, then finally verify the token with the db or cache etc.
Anyway this approach can also be used for Signalr, although its a bit more long winded and you are using dependency injection. You would basically wrap the hub calls with the desired attribute, then set up your DI/IoC configuration to intercept these calls, then either get the hub instance within your interceptor and get the cookie (or your custom authentication mechanism) from the request, verify it is all valid or not, and if not then throw a new HttpException("403", "Not authenticated"); which should kick the user out and return back before it even hits your hub method, this way you can put the logic in one place (your interceptor, or a class the interceptor consumes) then just wrap any method that needs to use this authentication using your attribute.
I use Ninject and the interception extension, but most major DI frameworks these days have some form of IoC plugin/extensions, such as Autofac, Windsor, Spring etc.
If you were not happy going down the route of introducing DI and/or AOP to your current project, then maybe you could just create a custom hub instance which contains your authentication logic and then just use that in your hubs, so ok you will still be manually calling some authentication logic from within each hub method you want to protect, but its less code, so something like:
public class AuthorisableHub : Hub
{
private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object
{
// Get your token from the querystring or cookie etc
}
private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token)
{
// Perform some validation, be it simple or db based and return result
}
protected void PerformUserAuthentication()
{
var token = GetSomeAuthenticationTokenFromRequest(Context.Request);
var isRequestValid = IsAuthenticationTokenValid(token);
if(!isRequestValid)
{ throw new HttpException(403, "<Some forbidden message here>"); }
}
}
public class MyFancyPantsHub : AuthorisableHub
{
public void TellAllClientsSomethingSecret(ISecret secret)
{
PerformUserAuthentication();
// Do stuff with the secret as it should have bombed the user out
// before it reaches here if working correctly
}
}
It is not perfect but would work (I think), also I am sure I once read somewhere that Hubs are newly instantiated for each request, and if this is indeed true, you could possibly just put this logic in your constructor if you want to apply the authentication to every action within the hub.
Hope that helps, or gives you ideas... would be interested in knowing how you did solve it in the end.
SignalR does not provide any additional features for authentication. Instead, it is designed to work with the authentication mechanism of your application.
Hubs
You should do authentication as you normally would and then use the Authorize attribute provided by SignalR to enforce the results of the authentication on the Hubs.
The Authorize attribute can be applied to an entire Hub or particular methods in the Hub. Some examples:
[Authorize] – only authenticated users
[Authorize(Roles = "Admin,Manager")] – only authenticated users in the specified .NET roles
[Authorize(Users = "user1,user2")] – only authenticated users with the specified user names
You can also require all Hubs to require authentication by adding the following method in the Application_Start method:
GlobalHost.HubPipeline.RequireAuthentication();
Persistent Connections
You can use the user object in the request to see if the user is authenticated:
request.User.IsAuthenticated