I am building a web application using an AngularJS front-end and a Spring Boot REST back-end (they are running on separate servers i.e. port 3000 and port 8443). The back-end is supposed to connect to multiple external services (with separate authentications) and provide endpoints for the front-end to use.
For security, I decided to use Apache Shiro. For simplicity, I will pretend there are just 2 external services (ES1 and ES2).
I have created 2 x AuthorizingRealm which connect to the respective external services and attempt authentication using the provided tokens.
In the doGetAuthenticationInfo method, if the login is successful, I return a SimpleAuthenticationInfo with the principal, credentials and the name of the realm.
In the doGetAuthorizationInfo method, I check the realm name of the principal and, if it checks out, I return a SimpleAuthorizationInfo with the role "USER" and a permission (e.g. ES1_permitted).
I also extended the UsernamePasswordToken class for each realm to separate usage even more (through the supports method).
In a configuration class, I create a bean for a DefaultWebSecurityManager that uses my two realms and a bean for the Shiro filter.
I added 4 filters:
anon AnonymousFilter
perm PermissionsAuthorizationFilter
es1 ES1Filter
es2 ES2Filter
My filter chain looks something like:
/api/es1/login -> anon
/api/es1/** -> es1, perms[ES1_permitted]
/api/es2/login -> anon
/api/es2/** -> es2, perms[ES2_permitted]
/** -> anon
Somehow, when I served front-end and back-end from the same server (no CORS), it seemed to work. However, now that CORS is an issue, I can't seem to get this to work as expected.
Is there a simpler way to achieve this complete separation of authentication/authorization? I am willing to switch to Spring Security if it can be done there as well.
PS: I am using the Java API, not configuration files (spring xml or shiro.ini).
Related
Hello I recently received a demand to migrate the ldap authentication service to oauth2 from a jsf project, but I have no idea where to start, from what I've been seeing in the project I have an ldap security domain configured in wildfly where I can make use of some features that comes from FacesContext as:
.login(username, password)
.getUserPrincipal()
.isUserInRole(rule)
.logout()
.invalidateSession()
What I would like to know is if there is a possibility to make my own security domain the same as the configured ldap, where I would implement the methods above, any content where I can start is welcome
I made an implementation of org.jboss.security.auth.spi.UsernamePasswordLoginModule;
I am using Shiro Security to secure a JSF project.
It is working as expected, including calls to a remote EJB (that is unsecured). However, when a call to the unsecure EJB is made, i have the following warn, but the method is executed without a problem:
IIOP1002: Principal propagation: Cannot find principal information in subject
What does this exactly mean? What should I do to fix this? I need to execute the method in a remote EJB from a secured application and this warning is getting dumped to the log everytime a call to the EJB is made (this occurs multiple times).
Edit:
The warn doesn't occur when I deploy the project in the same Glassfish server as the EJB.
Edit 2:
I thought about inserting the principal information in the InitialContext, before doing the call to the EJB, like this:
Hashtable env = new Hashtable();
env.put(Context.SECURITY_PRINCIPAL, SecurityUtils.getSubject().getPrincipal());
ctx = new InitialContext(env);
Still no luck.
SecurityUtils is from org.apache.shiro.SecurityUtils library.
Apache Shiro is an application layer security solution. As far as I can tell it is not integrated with your application server in any way.
A Java EE server normally expects to be in charge of authentication, authorisation, etc. Consequently it is then in a position to be able to propagate credentials correctly when making both local and remote EJB calls. This is how features like javax.annotation.security.RolesAllowed are implemented.
Shiro propagates its principal to javax.security.Principal, which remote EJBs don't understand. The Java principal has to be nulled out.
This is done in Shiro EE integration module which will be integrated into Shiro with version 2.0+
I have a simple web application which I am writing using spring-boot and storm path for user authentication. (I'm actually using spring-boot-starter-stormpath-thymeleaf)
I have a have the following request mapping in my controller
#RequestMapping(value = "/secure", method = RequestMethod.GET)
public String secure(Model mode, HttpServletRequest request) {
Account account = AccountResolver.INSTANCE.getAccount(request);
if (account != null)
return "secure";
else
return "redirect:/login?next=secure";
}
which forces a user to login to view the secure page. It works, but it doesn't feel like it is the most elegant of solutions. Is there a better way? I think a solution with filters should be possible but I cannot figure it out.
The current Stormpath Spring Boot starter does not (yet) have an authentication filter, but it will on future releases for those that want an out-of-the-box experience without having to use Spring Security or Apache Shiro.
That said, we're currently working on natively supporting Spring Security and Apache Shiro as Spring Boot starters that 'just work' with the Stormpath Spring Boot starter. Until we can release those, creating a custom servlet filter as you indicate is the best approach.
Are you also using the Stormpath Servlet as well?
If so, you could do what you need following this piece of documentation. This way you will only need to declare which are the resources of your application that you want to secure and Stormpath's authc filter will prompt for authentication when required.
If you're using Spring MVC, you should use Spring Security and have Stormpath acting as an authentication provider. Then use the standard Spring Security tools to declare access rules and inject the current user where needed.
I am using Spring4 with Spring Security 3.2.4.
I have some http configurations in my security configuration in order to host form based authentication and REST services (with authentication) together.
For the pages and REST services which require app-authentication everything works fine with my current configuration but for the pages which does not require authentication, such as login and register, the anonymous authentication is not initialised somehow. Speaking in Java:
SecurityContextHolder.getContext().getAuthentication() returns null.
I expect that anonymous authentication is initialised as the documentation (http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#introduction) refers:
Anonymous authentication support is provided automatically when using the HTTP configuration Spring Security 3.0 and can be customized (or disabled) using the element. You don’t need to configure the beans described here unless you are using traditional bean configuration.
Does anyone have an idea why does it not happen although the documentation refers? (Beside the fact, that the documentation for 3.2.4 refers to 3.0 version and some of the given configuration suggestions refer deprecated implementation)
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.