Security for Dropwizard admin servlet (version 1.1.1) - java

I'm using Dropwizard (1.1.1).
My security context is defined as such:
environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new BasicAuthenticator())
.setAuthorizer(new BasicAuthorizer())
.setRealm("SECURITY REALM")
.buildAuthFilter()));
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
environment.jersey().register(RolesAllowedDynamicFeature.class);
Recently I moved my Admin page into my web application. Code is right here:
environment.getApplicationContext().setAttribute(
MetricsServlet.METRICS_REGISTRY,
environment.metrics());
environment.getApplicationContext().setAttribute(
HealthCheckServlet.HEALTH_CHECK_REGISTRY,
environment.healthChecks());
environment.getApplicationContext().addServlet(
new NonblockingServletHolder(new AdminServlet()), "/admin/*");
How can I add security context to Dropwizard admin servlet?
I have already viewed this StackOverflow answer, but nothing seems to be working. Looks like everything in that answer is deprecated.

Well, the admin servlet is a plain old servlet, not a Jersey resource. Given that you are creating a new admin servlet (are you disabling the default admin context?) in the application context, you can simply register a servlet filter to the application context like this:
environment.getApplicationContext().addFilter(new FilterHolder(new AdminServletFilter()), "/admin/*", EnumSet.of(DispatcherType.REQUEST));
Your AdminServletFilter can authenticate the user any way you like, for example if you want to do basic auth, use this implementation.
That said, if your intention is to move your admin servlet to run on the same port as your application connector, the better way to do it is via config:
server:
type: simple
adminContextPath: /admin
applicationContextPath: /
connector:
type: http
port: 8080
Also, I have updated the question you linked to with a security handler implementation that works for the latest Dropwizard version here. With this in place, you can protect the admin servlet by registering the security handler:
environment.admin().setSecurityHandler(new AdminConstraintSecurityHandler("admin", "supersecret"));

Related

Spring Boot/Auth0 - How do I specify the connection?

I am working on setting up an application using Spring Boot and Auth0. We are refactoring from a legacy codebase to use Spring Boot. In the legacy code, the Auth0 URL is created manually by appending the URL parameters:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&connection=[removed]
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
With the Spring Boot configuration (guide here: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login), this is the URL that generates:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
The Spring Boot URL is giving me an error "[invalid_request] no connections enabled for the client".
I am missing the "connection" parameter with the Spring Boot setup. I have tested by manually copying the URL and adding the "connection" parameter and I get the login page. Without it, I get the error.
On Spring's configuration page (https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings), I don't see an option for Connection. I didn't see anything on the SecurityFilterChain that would allow me to change this either.
I see that Auth0.js has a function that allows a "connection" parameter (https://auth0.com/docs/libraries/auth0js). How do I add this using Spring Boot/Java?
EDIT
application.properties:
spring.security.oauth2.client.registration.auth0.client-id=[removed]
spring.security.oauth2.client.registration.auth0.client-secret=[removed]
spring.security.oauth2.client.registration.auth0.scope[0]=openid
spring.security.oauth2.client.registration.auth0.scope[1]=email
spring.security.oauth2.client.registration.auth0.scope[2]=profile
spring.security.oauth2.client.provider.auth0.issuer-uri=[removed]
EDIT 2
We were working in conjunction with Auth0 Support - they provided us the following information:
In case an Enterprise connection is the only enabled connection for an
application and the "connection" parameter is not specified on the
/authorize request, you need to enable the "show as a button" setting
on that enterprise connection, otherwise you will get "no connections
enabled for the client" error.
The "Display connection as a button" checkbox is on the "Login
Experience" tab of the connection setting page.
Weird configuration requirement - you can't go directly to the login page. You have to have a button to take you there. This did resolve the original issue; however, I marked #Codo answer below as accepted, as it did answer this question and appears it would work from initial testing.
You are looking for a way to add an additional parameter to the authorization URI. It's isn't as straightforward as one would like but doable.
Fortunately, it's described in Customizing Authorization and Token Requests with Spring Security 5.1 Client.
You probably want to implement the steps 2 and 4:
Add your own implementation of OAuth2AuthorizationRequestResolver, override both resolve() methods to call customizeAuthorizationRequest()
Implement customizeAuthorizationRequest() to add the additional connection parameter (OAuth2AuthorizationRequest already support additional parameters)
Implement a security configuration class to register CustomAuthorizationRequestResolver as the authorization request resolver
Several issues on GitHub ask for a simpler way. But the issues are still open (or closed as duplicates).
Update
Instead of clientRegistrationRepository() (at the end of step 2), you could declare clientRegistrationRepository as an injected dependency and the use it without parentheses:
#Autowired
private ClientRegistrationRepository clientRegistrationRepository;
Spring Security comes with with mostly preconfigured Auth0 module. Unless you're doing something specific, there's no need to construct URL yourself.
Have you done Spring configuration as said in the link you've posted: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login#configure-spring-security ?
# src/main/resources/application.yml
spring:
security:
oauth2:
client:
registration:
auth0:
...
Here's another option (untested):
In application.properties, specify all URLs separately. So instead of:
spring.security.oauth2.client.provider.auth0.issuer-uri=xyz.us.auth0.com
Specify:
spring.security.oauth2.client.provider.auth0.authorization-uri=https://xyz.us.auth0.com/authorize?connection=azuread
spring.security.oauth2.client.provider.auth0.token-uri=https://xyz.us.auth0.com/oauth/token
spring.security.oauth2.client.provider.auth0.jwk-set-uri=https://xyz.us.auth0.com/=.well-known/jwks.json
spring.security.oauth2.client.provider.auth0.user-info-uri=https://xyz.us.auth0.com/userinfo
Note that the authorization URI already includes the connection parameters. All the other parameters should then be appended.
You can get all the URIs at https://xyz.us.auth0.com/.well-known/openid-configuration (just replace "xyz" and put the URL in your browser).

Secure a Java web app using the Spring Boot Starter for Azure Active Directory JWT token algorithm problem

I'm created java web application using spring boot starter for azure active directory step by step like is described in:https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory
My application with my azure account work fine when i open localhost:8080 it redirects me to azure where I do the login and then I'm redirected back to my app.
Problem is when i try to configure this dummy app with azure AD account from my customer. Here also when i open my app host app redirects me to azure login and after login i got error like in screenshot
and here is my application.properties
azure.activedirectory.tenant-id=placeholder
azure.activedirectory.client-id=placeholder
azure.activedirectory.client-secret=placeholder
azure.activedirectory.object-id=placeholder
azure.activedirectory.user-group.allowed-groups=group1
azure.activedirectory.session-stateless=true
security.oauth2.authorization.token-key-access=permitAll()
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
application.baseurl.logout.redirect=https://mydomain:8081/
application.groups.for.displaying=
application.groups.for.filtering=
server.port=8081
server.ssl.enabled=true
server.ssl.trust-store=/apps/tomcat/conf/trusted.jks
server.ssl.trust-store-password=mykeys
server.ssl.key-store=/apps/tomcat/conf/.keystore
server.ssl.key-store-password=f213495a0be855c4ab190a1f84cc18cd
server.ssl.key-store-type=JKS
server.ssl.key-alias=key-dev-ui
server.ssl.key-password=f213495a0be855c4ab190a1f84cc18cd
my configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests().anyRequest().authenticated().and().oauth2Login().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().oauth2Client();
}
Please check below points:
The issue may arise when the issuer value obtained from token is from different endpoint (v2) than expected.Please make sure to use latest version of spring boot api and check the same to be in dependencies.
You need to set the redirect URL as http://localhost:8080/login/oauth2/code/azure or http://localhost:8080/login/oauth2/code/ in the portal.You can configure other value according to your app in place of localhost:8080 .This redirect uri must be configured in your application properties.
Make sure to expose api and make sure the permissions are also configured and granted admin consent.
. Give default scope (make sure to add the scope in code)or directly give the scopes present in the app (check in app code) such as User.read ,file.read or offline_access and provide delegated permsissions in portal like below(if those are present in code ).
(or)
and grand admin consent
Also see springboot starter dev guide | ms docs and please check references below.
You may provide other configuration details by editing the question if above are not the cases to investigate further.
References:
spring-rest-azure-ad-oauth
using-spring-security-with-azure-active-directory-mga

Tomcat prefix to every Spring url with Spring Security

Currently I'm facing issue with redirecting application which is behind proxy server:
To see application I need to go to:
http://myserver.net/PREFIX/configuration
And I need to add PREFIX to every url which will be returned by spring. Currently after successful logging with spring security when I return
.successForwardUrl("/configuration")
It's redirecting me to url address which is not existing:
http://myserver.net/configuration
Is there any possibility to add Tomcat prefix to dispatcher servlet? To make somehow default path for the application:
http://myserver.net/PREFIX/
I was trying to use:
server.servlet.contextPath=PREFIX
But problem is that when I use context path, I need to go
http://myserver.net/PREFIX/PREFIX/configuration
To be redirected properly to spring controller. Maybe there is possibility to set up context path but only for response?

Logout all still-logged-in users from WebApp using Shiro and Spring WebMVC (Java8, Spring 4.x)

I'm fairly new to shiro, so here's my question:
I've implemented Shiro into an application using Spring WebMVC / Spring Framework (4.x)on a Tomcat 8 container. The Roles and Permissions are working fine so far, the login, too, but Problem is, that sessions are still working when I redeploy my war-file / stop/restart the server, which is not intended here.
Would be great to get a hint what I have to do to implement something like an "auto-logout" of all logged-in users after a redeploy/restart of the server, e.g. redirecting to loginpage and showing a modal or s.th. saying "you've been logged out due to [reasons]".
Best regards,
Dominik
You can use the SessionDAO interface, but you need to do extra configuration to have shiro use a SessionDAO as described here:
http://shiro.apache.org/session-management.html#SessionManagement-SessionStorage
When you have configured it correctly you can do stuff like:
DefaultSecurityManager securityManager = (DefaultSecurityManager) SecurityUtils.getSecurityManager();
DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
Collection<Session> activeSessions = sessionManager.getSessionDAO().getActiveSessions();
for (Session session: activeSessions){
session.stop();
}
Only, if you want to have a message like you suggest, you cannot do this after you have removed the session as the server has no clue anymore if the browsers session was logged out.
Instead what you can do is write something to the db above where the session.stop(), i.e. set a flag that the next request should result in the autologout action, you could probably implement the autologout logic using a Filter.

Setting the Roles for #RolesAllowed in JAX-RS using jersey

I tried using Basic Authentication by changing the server.xml config of Tomcat 6.0 but it did not worked: BASIC authentication in jersey JAX-RS service and Tomcat 6.0 getting failed
Hence I am opting a way where no server specific config is needed and I can add up the roles directly in my code (either client or server; not sure about theavailable options).
Please provide me some ideas about the possible options for setting the user roles so that I can authenticate my Web Service methods using the #RolesAllowed annotation.
You need to go back and figure out why your security constraints weren't working. Maybe start with the default file realm before moving on to JDBC realms. #RolesAllowed in an annotation that triggers behavior in the container.
If you really want to do it yourself (a bad idea) they you'd probably start by creating a custom servlet filter that implemented the entire basic http challenge mechanism. Next you'd have to replace the SecurityContext provider in Jersey.
They "thing" that enables #RolesAllowed in jersey is this: http://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/RolesAllowedResourceFilterFactory.java Which, by the way, don't forget to add as an init-param to your jersey servlet. The RolesAllowedResourceFilterFactory gets its security info from an injected SecurityContext which I'm sure at some point just delegates off to the Servlet API for credential info.
So basically if you don't want to take the time to get security constraints working you are going to end up replacing most of the chain...like I said, a bad idea.
The features on application servers are there to keep you from having to spend time creating infrastructure code, if you write your own infrastructure code you're going to have a bad time.

Categories

Resources