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))
Related
I have mu backend application in asp.net web api (frontend is angular 8 app)
i have method in controller:
[RoutePrefix("Payment")]
public class PaymentDeadlineController : ApiController
{
DKServiceClient DkService = new DKServiceClient();
SrvPartlyPayment PartlyPayment = new SrvPartlyPayment();
[Route("GetNotified")]
public void GetNotified()
{
DkService.SrvC_CPCheckIsActive();
}
}
How to prevent entering this method GetNotified() when someone opens browser and types http://HostedLocation/Payment/GetNotified in the url?
If you are looking to secure your API from unauthorized access,
You can add [Authorize] attribute in the web api controller and enable Authorization for your API in your startup.cs.
Your front end application can send request to API along with a token issued by your identity provider to API and get response,
while other anonymous users will not have token and hence cannot invoke your method using browser or any other tools like postman.
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
}
I have multiple restful API components implemented using ASP.NET Core. I am not using Event Driven Design or any messaging broker service.
I want to keep it simple, so
Let's say I have 3 restful independent components (with independent ASP.NET Core Projects) that are published to the same IIS in addition to the Identity server provider:
Navigation: that retrieve menus from its own database
Authorization: that deals with the permissions and security
Notifications
Identity Server: provides Jwt access tokens for authenticated users to authorize him access the apis.
Apart from the external communication from the client to the Apis where an API Gateway should handle all client requests. There are some sort of communication that is done internally. A good example is getting menus for the user:
The user gets an access token after successful log in
Then he requests the menus he can view, so a request is forwarded to Navigation API
Navigation API issues an internal request to Authorization API in order to check what permissions the user has to limit his access to certain menus.
Right Now, I am managing the communication by a common library called Service Proxies, which has all the api urls hard coded in cs file (which is just for trying the concept)
public static class Config
{
public static class ServiceURLs
{
public const string AuthorizationAPI ="http://localhost:port/api/Authorization/" ;
}
}
public class AuthorizationServiceProxy : IAuthorizationServiceProxy
{
//ServiceProxy is a custom class that issue http requests in order to get responses
private ServiceProxy _serviceProxy;
public AuthorizationServiceProxy(string accessToken)
{
_serviceProxy = new ServiceProxy(Config.ServiceURLs.AuthorizationAPI, accessToken);
}
public async Task<List<Permission>> GetUserPermissions()
{
var route = "GetUserPermissions";
var result = await
_serviceProxy.GetHttpResponseContentAsType<List<Permission>>(route);
return result;
}
AuthorizationProxy and all proxies will be just to issue a request from an API to another one.
How would an interprocess communication would be handled in my case?
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 am in reference to Spring Security documentation about configuring CSRF protection:
Instead by default Spring Security’s CSRF protection will produce an
HTTP 403 access denied. This can be customized by configuring the
AccessDeniedHandler to process InvalidCsrfTokenException differently.
see here: http://docs.spring.io/spring-security/site/docs/3.2.6.RELEASE/reference/htmlsingle/#csrf-configure
I am unsure how to configure my handler in order to deal with the invalid CSRF token.
private AccessDeniedHandler accessDeniedHandler() {
return new AccessDeniedHandler() {
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
// TODO: deal with InvalidCsrfTokenException
response.setStatus(HttpStatus.FORBIDDEN.value());
}
};
}
I use angular on the client side to communicate with my Spring app in REST.
What is the best way to deal with stale/invalid CSRF tokens?
Should I use the the AccessDeniedHandler in order to add a custom http response header indicating that the CSRF token is invalid and process that on the client side? But how can I request a fresh CSRF token from JS?
Is there another and better way to proceed and how can I
process the InvalidCsrfTokenException differently
?
If you provide a detailed error message then use the AccessDeniedHandler. The handler manage the InvalidCsrfTokenException and MissingCsrfTokenException
And why do you want to generate the csrf token? Everytime you request a site spring will generate it for you. But if you really want to implement an own csrf strategie take a look at the CsrfAuthenticationStrategy
Spring call this class everytime in the SessionManagementFilter