I have JSP with calling to my Session Bean, I've implemented this via JNDI InitialContext(). Session Bean class is having a #RolesAllowed annotation with one defined user. I want to restrict users who can call methods of this bean.
Application Sever connected to TAM/WebSEAL via junction. So I can see that authenticated users have defined "iv-user", "iv-groups", "iv-creds" http request header values, unauthenticated - don't. But then I trying to call any of bean methods I've got a Security Exception like trying to access as unauthenticated user. Moreover, I don't see userPrincipal when at the response of request.getUserPrincipal()
How to pass security context from WebSEAL / Tivoli Access Manager into EJB and use it for JAAS annotations?
I've found one solution:
1. Switch WebSphere to use a Standalone LDAP registry, set link as Trusted (actually it not necessary)
2. Setup LTPA authentication between WAS and WebSEAL
after these JSP should get security context and pass to the called methods.
3. Define security constraints inside target web application.
Related
I am working on an application which requires an integration of a proprietary SSO with spring security. The application uses spring boot, and the requirement is that we use the authentication from internal proprietary SSO module and authorization from the existing application. The existing application's authentication system has to be replaced with internal proprietary SSO's authentication module. I went through a few documents and understood that it is possible as the spring is module based.
While working on the application I noticed that we are using FilterRegistrationBean to initialize one filter, and another filter is added to the chain via WebSecurityConfigurerAdapter's configure(HttpSecurity http) method.
Can someone please let me know if this will be treated as two different chains? If so, how are the chains checked for filtering out the details?
Can I just remove the filter we are adding via WebSecurityConfigurerAdapter's configure(HttpSecurity http) method and replace the existing filter that is registered via FilterRegistrationBean with the filter (with highest precedence) from internal proprietary SSO?
OK so we do exactly what you're asking for in one of our systems. We have this working in Spring boot 1 and 2. These are the steps to take.
Create a bean extending AbstractPreAuthenticatedProcessingFilter. Implement getPreAuthenticatedPrincipal and getPreAuthenticatedCredentials to extract the authenticated user and optional credentials (e.g. a certificate) from your SSO system. Create a FilterRegistrationBean for this filter bean otherwise thanks to spring boot's component scanning it'll end up in the main filter chain as well as the security filter chain.
Create a user details (authorization) service bean implementing AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken>. Override loadUserDetails to take your authenticated token and use it to add permissions in the form of GrantedAuthority lists.
In your WebSecurityConfigurerAdapter bean subclass do the following:
Inject your subclass of AbstractPreAuthenticatedProcessingFilter and also your subclass of AuthenticationUserDetailsService.
Add a class member of type PreAuthenticatedAuthenticationProvider and initialise it with new (it's not a bean).
In configure(HttpSecurity) initialise your filter bean with an authentication manager: yourBean.setAuthenticationManager(authenticationManager()) then ensure your filter is included:
http.addFilter(yourBean)
.authorizeRequests()
.requestMatchers(...)
Override configure(AuthenticationManagerBuilder) and initialise the PreAuthenticatedAuthenticationProvider you created in step (2) with your implementation of the authentication and authorization beans.
this.preAuthProvider.setPreAuthenticatedUserDetailsService(this.userDetailsService);
this.preAuthProvider.setThrowExceptionWhenTokenRejected(true);
authBuilder.authenticationProvider(this.preAuthProvider);
That should be all. Hope that helps.
I needed to change JSESSIONID's domain to ".something.com" in a context.xml file:
<Context path="/test" sessionCookiePath="/" sessionCookieDomain=".something.com" useHttpOnly="true" />
After that, when I perform a httpSession.invalidate() the session is reset but JSESSIONID value does not change.
I'm using Java 7, Spring MVC and Tomcat 7. I also tried to remove the JSESSIONID cookie manually, but it seems that Tomcat or Spring are not letting I change its value.
This may difficult troubleshooting on my system. I'd like to know if it's possible to change this behavior either on Spring or in Tomcat.
I found the problem in Tomcat's documentation:
"Note: Once one web application using sessionCookiePath="/" obtains a session, all subsequent sessions for any other web application in the same host also configured with sessionCookiePath="/" will always use the same session ID. This holds even if the session is invalidated and a new one created. This makes session fixation protection more difficult and requires custom, Tomcat specific code to change the session ID shared by the multiple applications."
Source: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html
The issue is related to cookie path, and not with domain
Assuming you're using Spring Security, you can configure the session logout handler to delete the cookie for you.
...
<logout delete-cookies="JSESSIONID">
...
Or, in Java configuration, in a WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.logout()
.deleteCookies("JSESSIONID");
}
If you're not using Spring Security, you can probably install a Filter object into Spring's existing filter chain to delete the Set-Cookie header in outgoing requests whose sessions have been invalidated (or on whatever condition you specify, at that point). This is more or less what Spring Security's logout handlers do, anyway.
i have the following setup.
server1: i am using spring security v3.1.4 in one application. this application is running on its own server (e.g. tomcat at server1.mydomain.com).
server2: i have another 3rd party web application running on a different server (e.g. tomcat at server2.mydomain.com). this applicaton is pluggable in that it allows me to install jars to dynamically modify behavior at runtime. its purpose is to serve content.
users and resource access are managed on server1. content is delivered by server2. on server2, if a resource request comes in, i need to ask server1 if the user is logged in. is this possible to do with spring security? i imagine i would pass in the username with the resource request (e.g. http://server2.mydomain.com?getFileId=1&username=johndoe#gmail.com).
i read a little bit on the spring security website and SSO seems to be the way to go (e.g. using Central Authentication Service). but that seems like an overkill. our architecture already has several servers running.
integration (e.g. the webapp using spring security)
media (e.g. the 3rd party webapp)
elastic search (a cluster)
mysql (a cluster)
if possible we would like to have a minimalist system (but our system isn't small, given our investments and assumptions using rdbms/IR clusters).
any help is appreciated.
One possible way of achieving this - although it's not something I've tried myself - could be to expose Spring Security's SessionRegistry in server1 via a simple REST based controller. That would then allow server2 to remotely query authenticated users in server1 by making a simple HTTP GET request.
It's probably worth having a read of the Session Management section of the Spring Security docs to determine how to access the SessionRegistry. The basic setup I think is to specify a <session-management> tag inside the <http> section of your config on server1.
<security:session-management>
<security:concurrency-control session-registry-ref="sessionRegistry"/>
</security:session-management>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
You would also need to add a listener to the web.xml of server1
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
The controller that you would need to create on server1 could then be autowired with the SessionRegistry
#Autowired
private SessionRegistry sessionRegistry
From there, you can use sessionRegistry.getAllSessions() to determine whether a username (principal) passed in a request to the controller is logged in on server1.
More of an idea than a concrete answer - but may give you an avenue to explore.
I'm creating a restful web service using Resteasy. One thing I need to do is to secure the service using a standard HTTP auth request. The tricky part is that the service is multi-tenant and needs to use one of the path parameters to determine the security realm.
There are a lot of articles typical of this link which describe setting up a single-tenant service. What I can't find is what to configure, and what interfaces to implement to describe my own security which is based on a path parameter + the username in the HTTP authentication method.
I envision that prior to calling any of the application logic, tomcat/resteasy would call a SecurityProvider (or whatever) interface with the HttpServletRequest and have me either throw a 401 or return a SecurityContext that gets passed to the JAX-RS handlers. In that routine, I would inspect the path parameters, and make a determination based on parameter+username+password given in the Basic/Digest/Form.
Is there any such beast?
I thought I'd update this since there's bee little activity on this question.
It looks like there's no baked in feature to do what I envisioned, so instead I extended the RestEasy servlet and added the security checks in my override before passing control back to the stock RestEasy servlet.
Seems to work well.
i want code to check whether the user in logged in or not. I get replied with context that to use HttpServletRequest.getUserPrincipal(). But i do not know how to set the username in servlet so that it is further called by getUserPrincipal()
Thank in advance
To get a user via getUserPrincipal, you need to authenticate using container-managed authentication. This usually (always?) involves setting security constraints and authentication mechanisms in your web.xml. There are several examples in the JEE5 tutorial. How usernames/passwords are registered is an implementation detail that will depend on the servlet container and how it is configured.