How to retrieve UserDetails with Spring Security 3? - spring

www.someurl.com - public access not intercepted by Spring Security 3.
www.someurl.com/admin - intercepted by Spring Security 3. Works fine.
I log into a page under www.someurl.com/admin. Then I change the url to www.someurl.com in the same window tab. I am working within the same http session so I expect to be able to retrieve user login details.
The public url request is handled by a dedicated controller. Within this controller, I have a wired user service. The implementer of this service is attempting to retrieve credentials but can't - Authentication object is null.
Authentication a=SecurityContextHolder.getContext().getAuthentication();
userDetails=(UserDetails) a.getPrincipal();
=== UPDATE =========================
When I inspect the HttpSession in the public url request controller, I see this attribute:
{SPRING_SECURITY_CONTEXT=org.springframework.security.core.context.SecurityContextImpl#ed20eaf7: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ed20eaf7: Principal: org.springframework.security.core.userdetails.User#586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMINISTRATOR,AUTHOR,EDITOR,READER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#380f4: RemoteIpAddress: 127.0.0.1; SessionId: 43A582157C5813018632ACDD7499CF7D; Granted Authorities: ADMINISTRATOR, AUTHOR, EDITOR, READER}

If you want to get security details like you are, Spring Security must intercept the url, otherwise there won't be any security information. You can add the following to your spring security config:
<security:http pattern="/" security='none' />
This means that spring security will let everyone see the root url (whether logged in or not), but spring security will process the url, meaning your controller against the root url will be able to get the current user login details from SecurityContextHolder

Related

How to configure spring boot to validate JWT token with call instropection endpoint of authorization server

I have simple resource server application with spring boot, this is yaml file:
server:
port: 8081
servlet:
context-path: /resource-server-jwt
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8083/auth/realms/rasool
Now, i want to make change in configuration or code to force spring security to validate JWT token with calling introspection endpoint of authorization server instead of local validation with keys, but i didn't find any way as spring security docs says.
Spring-boot spring.security.oauth2.resourceserver.jwt.* configuration properties are for JWT decoder.
For token introspection, use spring.security.oauth2.resourceserver.opaque-token.* properties instead (token being in whatever format, including JWT). "opaque" means that tokens are considered a "black-box" by resource-server which delegates validataion and attributes retrieval to authorization-server on introspection endpoint:
server:
port: 8081
servlet:
context-path: /resource-server-jwt
spring:
security:
oauth2:
resourceserver:
opaque-token:
introspection-uri: http://localhost:8083/auth/realms/rasool/protocol/openid-connect/token/introspect
client-id: change-me
client-secret: change-me
Introspection uri from .well-known/openid-configuration
If you are using Java configurationn the switch is about the same: replace http.oauth2ResourceServer().jwt()... with http.oauth2ResourceServer().opaqueToken()...
A few notes about declared clients on authorisation-server
Resource-servers introspect token on authorisation-server introspection endpoint using client-credentials flow: for each and every request it process, resource-servers will send a request to authorization-server to get token details. This can have serious performance impact. Are you sure you want to switch to token introspection?
As a consequence, in the properties above, you must configure a client with:
"Access Type" set to confidential
"Service Accounts Enabled" activated
Create one if you don't have yet. You'll get client-secret from "credentials tab" once configuration saved.
Note you should have other (public) clients to identify users (from web / mobile apps or REST client) and query your resource-server on behalf of those users.
From the authorization-server point of view, this means that access-tokens will be issued to a (public) client and introspected by antoher (confidential) client.
Complete working sample here
It does a few things useful for resource-servers:
authorities mapping (choose attributes to parse user authorities from, prefix & case processing)
CORS configuration
stateless-session management
CSRF with Cookie repo
anonymous enabled for a list of configured public routes
401 (unauthorized) instead of 302 (redirect to login) when trying to access protected resources with missing or invalid Authorization

Spring Boot: Error publishing SessionConnectedEvent

I have Spring Stomp setup on a project, everything is working fine but I keep getting this as errors in the server logs.
2021-02-17 05:02:26.875 ERROR 23773 --- [oundChannel-914] o.s.w.s.m.StompSubProtocolHandler : Error publishing SessionConnectedEvent[GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT_ACK, simpConnectMessage=GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={x_from_wss=[true], accept-version=[1.1,1.0], heart-beat=[0,0]}, simpSessionAttributes={}, simpHeartbeat=[J#1dbcdf26, simpUser=org.springframework.security.authentication.UsernamePasswordAuthenticationToken#cda212a8: Principal: me.xxxx.xxx.user.security.UserLoginDetails#325d7812; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities, simpSessionId=ml2gvecs}], simpUser=org.springframework.security.authentication.UsernamePasswordAuthenticationToken#cda212a8: Principal: me.xxxx.xxx.user.security.UserLoginDetails#325d7812; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities, simpSessionId=ml2gvecs}]]
I tried setting up Event handlers for the websocket as well but still it continues to show up in the logs. I understand its an acknowledgement message on the connect from the client but it should not fail. Any advise will be much appreciated.
The error says:
Not granted any authorities
If you are using something like Spring Security, make sure to pass a collection of Granted Authorities, once authenticated.
You could do something like this
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken= new UsernamePasswordAuthenticationToken(
"AuthenticatedUserName", "Credentials", Collections.singleton((GrantedAuthority) () -> "USER")
);
In case you are not using Spring Security, you could set up a Authenticated User Token via Channel Interceptor.
Follow thelink below, to see how you can setup Channel Interceptor for you WebSocket Connection
Websocket Authentication and Authorization in Spring

Can't get spring-boot /health indicator to display full content

Trying to get the full content of the /health endpoint. I've set the following:
endpoints.health.sensitive=true
management.security.enabled=true
and I'm successfully authenticating (earlier, to gain access to the endpoint in the first place), as shown by the log snippet below:
2016-11-06 10:48:18,936 [XNIO-3 task-1]DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'endpoints.health.sensitive' in [applicationConfig: [classpath:/application.properties]] with type [String] and value 'true'
2016-11-06 10:48:19,109 [XNIO-3 task-1]DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#4542ffee
2016-11-06 10:48:19,109 [XNIO-3 task-1]DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext 'org.springframework.security.core.context.SecurityContextImpl#760f603a: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#760f603a: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl#375540cb: ......; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ......; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: .....' stored to HttpSession: 'io.undertow.servlet.spec.HttpSessionImpl#768a4e99
2016-11-06 10:48:19,148 [XNIO-3 task-1]DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [UP {}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#eae8a50]
But one can see by the last line that I'm only being shown the "non-sensitive" information (there are db connections in the app which show up if I set both of the spring-boot properties to false.
From what I've read, the db status should be displayed.
What am I missing?
Possible duplicate of Spring Boot Actuator /health endpoint does not show database or file system information
I think you need to enable db health checks by default
management.health.db.enabled=true # Enable database health check.
management.health.defaults.enabled=true # Enable default health indicators.
management.health.diskspace.enabled=true # Enable disk space health check.
Also there are auto-configured health indicators for various backend implementations by Spring Boot
see: http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#_auto_configured_healthindicators
Hope it helps.
put a breakpoint in HealthMvcEndpoint (https://github.com/spring-projects/spring-boot/blob/master/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java) and in debug, you'll be able to understand how the health response is built, based on the underlying components exposing health infos and the security config (exposeHealthDetails method).
Add the following property in the properties file to resolve the problem:
management.health.db.enabled=true

remove OAuth2AuthenticationProcessingFilter from/oauth/token filter chain

I am trying to implement OAuth2 into my Spring Boot app. When making a call to /oauth/token using a password grant, I am able to authenticate using Basic auth with a username/password against a database. The authentication object is loaded into the security context and the filter continues. However I noticed that further down the line the OAuth2AuthenticationProcessingFilter is called and cleans out the security context b/c no OAuth bearer token is found. This ultimately results in an authentication failure at the TokenEndpoint.postAccessToken method (e.g. /oauth/token).
Is it expected that the OAuth2AuthenticationProcessingFilter would be called during a /oauth/token call? If not, any ideas why? If it is expected what is the best fix/work around for this issue, to set stateless on the OAuth2AuthenticationProcessingFilter to false? Not sure if that is a good idea or not...
Some relevant info, I am using xml config for my spring security settings and JavaConfig for the rest. The grant type is password on the /oauth/token call.
Any help is greatly appreciated. Below are some log messages for context on what I am seeing.
09/30/15 22:42:50.899 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.c.ClientCredentialsTokenEndpointFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.oauth2.provider.OAuth2Authentication#9d98054f: Principal: testUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_USER
09/30/15 22:42:50.899 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in headers. Trying request parameters.
09/30/15 22:42:50.899 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in request parameters. Not an OAuth2 request.
09/30/15 22:42:50.899 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter - Clearing security context.
09/30/15 22:42:50.900 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter - No token in request, will continue chain.
09/30/15 22:42:50.900 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in headers. Trying request parameters.
09/30/15 22:42:50.900 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.BearerTokenExtractor - Token not found in request parameters. Not an OAuth2 request.
09/30/15 22:42:50.900 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter - No token in request, will continue chain.
09/30/15 22:42:50.934 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Looking up handler method for path /oauth/token
09/30/15 22:42:50.937 [http-nio-9931-exec-8] DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
09/30/15 22:42:50.958 [http-nio-9931-exec-8] INFO o.s.s.o.p.endpoint.TokenEndpoint - Handling error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.
09/30/15 22:42:51.070 [http-nio-9931-exec-8] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
09/30/15 22:42:51.070 [http-nio-9931-exec-8] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

Deploy Spring Integration in Bitnami Stack

I am stuck with a problem and I can't figure out what is happening...
I have built an rest-api using spring integration. When I deploy the app in my local tomcat 7 everything works OK.
When I deploy it in mi bitnami stack (same tomcat version) and try the same request (changing the host), authentication step is OK but no mapping is found...
Basic authentication wih Spring Security is well done
2013-07-02 12:12:04,228 DEBUG intercept.FilterSecurityInterceptor -
Previously Authenticated:
org.springframework.security.authentication.UsernamePasswordAuthenticationToken#95f956f:
Principal: org.springframework.security.core.userdetails.User#36ebcb:
Username: user; Password: [PROTECTED]; Enabled: true;
AccountNonExpired: true; credentialsNonExpired: true;
AccountNonLocked: true; Granted Authorities: ROLE;
Credentials: [PROTECTED]; Authenticated: true; Details:
org.springframework.security.web.authentication.WebAuthenticationDetails#0:
RemoteIpAddress: 85.136.69.37; SessionId: null; Granted Authorities:
ROLE 2013-07-02 12:12:04,228 DEBUG
vote.AffirmativeBased - Voter:
org.springframework.security.web.access.expression.WebExpressionVoter#346946d5,
returned: 1 2013-07-02 12:12:04,228 DEBUG
intercept.FilterSecurityInterceptor - Authorization successful
Spring Integration mapping is not found
2013-07-02 12:12:04,228 DEBUG intercept.FilterSecurityInterceptor -
RunAsManager did not change Authentication object 2013-07-02
12:12:04,228 DEBUG web.FilterChainProxy -
/ptgapi/v1/clients/1/events/400 reached end of additional filter
chain; proceeding with original chain 2013-07-02 12:12:04,228 DEBUG
support.OpenEntityManagerInViewFilter - Opening JPA EntityManager in
OpenEntityManagerInViewFilter 2013-07-02 12:12:04,229 DEBUG
servlet.DispatcherServlet - DispatcherServlet with name 'Destiny
Customer Information Search Restful Web Service' processing GET request for [//PTG/ptgapi/v1/clients/1/events/400]
2013-07-02 12:12:04,229 WARN servlet.PageNotFound - No mapping
found for HTTP request with URI
[//PTG/ptgapi/v1/clients/1/events/400]
in DispatcherServlet with name 'Destiny Customer Information Search
Restful Web Service'
Any idea what is happening?
Update
I have found that Spring Integration is using a double slash (//) in local and a simple slash (/) in bitnami being the same war.
Could be the way Spring Integration splits the URL (local environment is windows and bitnami is Ubuntu)?
LOCAL
2013-07-02 15:31:28,443 DEBUG servlet.DispatcherServlet - DispatcherServlet with name 'Destiny Customer Information Search Restful Web Service' processing GET request for [/PTG/ptgapi/v1/clients/1/events/400]
2013-07-02 15:31:28,449 DEBUG inbound.UriPathHandlerMapping - Matching patterns for request [/ptgapi/v1/clients/1/events/400] are [/ptgapi/{apiVersion}/clients/{clientId}/events/{eventId}]
BITNAMI
2013-07-02 13:37:45,469 DEBUG servlet.DispatcherServlet - DispatcherServlet with name 'Destiny Customer Information Search Restful Web Service' processing GET request for [//PTG/ptgapi/v1/clients/1/events/400]
2013-07-02 13:37:45,470 WARN servlet.PageNotFound - No mapping found for HTTP request with URI [//PTG/ptgapi/v1/clients/1/events/400] in DispatcherServlet with name 'Destiny Customer Information Search RestfulWeb Service'
I have found that changing servlet-mapping to this one avoid this strange behaviour:
<servlet-mapping>
<servlet-name>Destiny Customer Information Search Restful Web Service</servlet-name>
<url-pattern>/rootCommonPath/*</url-pattern>
</servlet-mapping>

Resources