Controller (web request/antMatcher) security vs method(service) level security - java

In Spring Security I see URL's secured with:
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN");
I also see that there is method level security:
#PreAuthorize("hasRole('ADMIN')")
Are the antMatchers used to secure the URL while the #PreAuthorize used to secure interfaces?
If the antMatcher secures the URL that calls the interface already, then why the need to separately secure the interface method?
Could you use method level security on the controller like:
#PreAuthorize("hasRole('ADMIN')")
#GetMapping("/dashboard/person")
public String findEvent(Model model, HttpServletRequest request) {
....

Web security and method security are two different ways to secure your application, see Spring Security Reference:
Why not just use web.xml security?
Let’s assume you’re developing an enterprise application based on Spring. There are four security concerns you typically need to address: authentication, web request security, service layer security (i.e. your methods that implement business logic), and domain object instance security (i.e. different domain objects have different permissions). With these typical requirements in mind:
[...]
Web request security: The servlet specification provides an approach to secure your request URIs. However, these URIs can only be expressed in the servlet specification’s own limited URI path format. Spring Security provides a far more comprehensive approach. For instance, you can use Ant paths or regular expressions, you can consider parts of the URI other than simply the requested page (e.g. you can consider HTTP GET parameters) and you can implement your own runtime source of configuration data. This means your web request security can be dynamically changed during the actual execution of your webapp.
Service layer and domain object security: The absence of support in the servlet specification for services layer security or domain object instance security represent serious limitations for multi-tiered applications. Typically developers either ignore these requirements, or implement security logic within their MVC controller code (or even worse, inside the views). There are serious disadvantages with this approach:
a. Separation of concerns: Authorization is a crosscutting concern and should be implemented as such. MVC controllers or views implementing authorization code makes it more difficult to test both the controller and authorization logic, more difficult to debug, and will often lead to code duplication.
b. Support for rich clients and web services: If an additional client type must ultimately be supported, any authorization code embedded within the web layer is non-reusable. It should be considered that Spring remoting exporters only export service layer beans (not MVC controllers). As such authorization logic needs to be located in the services layer to support a multitude of client types.
c. Layering issues: An MVC controller or view is simply the incorrect architectural layer to implement authorization decisions concerning services layer methods or domain object instances. Whilst the Principal may be passed to the services layer to enable it to make the authorization decision, doing so would introduce an additional argument on every services layer method. A more elegant approach is to use a ThreadLocal to hold the Principal, although this would likely increase development time to a point where it would become more economical (on a cost-benefit basis) to simply use a dedicated security framework.
d. Authorisation code quality: It is often said of web frameworks that they "make it easier to do the right things, and harder to do the wrong things". Security frameworks are the same, because they are designed in an abstract manner for a wide range of purposes. Writing your own authorization code from scratch does not provide the "design check" a framework would offer, and in-house authorization code will typically lack the improvements that emerge from widespread deployment, peer review and new versions.
Spring Security recommends method security, see Spring Security Reference:
10.1.4 Request Matching and HttpFirewall
[...]
In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level. URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated. You should try and restrict yourself to using a few simple ant paths which are simple to understand. Always try to use a "deny-by-default" approach where you have a catch-all wildcard ( / or ) defined last and denying access.
Security defined at the service layer is much more robust and harder to bypass, so you should always take advantage of Spring Security’s method security options.
Spring Security recommends applying method security at the service layer rather than on individual web controllers, see Spring Security Reference:
I have added Spring Security’s element to my application context but if I add security annotations to my Spring MVC controller beans (Struts actions etc.) then they don’t seem to have an effect.
[...]
Generally we would recommend applying method security at the service layer rather than on individual web controllers.

Related

Concept behind how java clients authenticate with JEE server like weblogic, jboss etc

I have been going through lot of documentation to understand what is the standard way (if there is any) in which the java client authenticates themselves with the applications deployed on server container like weblogic, jboss etc.
After reading about JAAS & JNDI authentication documentation for weblogic, I am able to understand the flow, but no documentation answers the below queries
Are JAAS and JNDI the only available methods for authenticating java clients ?
What I understood so far is, that each application server can provide its own abstraction layer to perform authentication, for example OPSS in weblogic, but eventually they all depend on native authentication methods available in JEE framework. Please point out if this assumption is not correct.
The confusion is greatly amplified as some article mention that JAAS security doesn't exists in JEE. Is that valid for java 7+ too?
The oracle weblogic documentation I have been going through clearly states JNDI & JAAS as the standard authentication approaches, and even goes to the extent to specifying JAAS as being preferred over JNDI authentication.
https://docs.oracle.com/cd/E28280_01/web.1111/e13711/fat_client.htm#SCPRG225/
Here is clarification I got based on the material read during last two days.
Most basic thing - All application servers provided provide an identity store, that can store users & groups. Applications can refer to this identity store, as when it is deployed on the server.
A Caller or User is an individual named identity defined in an identity store.
https://dzone.com/refcardz/getting-started-java-ee?chapter=1
How the applications execute authentication?
Based on pure JEE framework, the authentication methods can be classified based on the type of application it secures:
Web Application Authentication
Declarative:
We use either deployment descriptors or #annotations to specify these authentication enablers:
a. Which options to use for rendering authentication i.e. basic (browser popup), custom form, SSL, etc.
b. Which resources(URL patterns) need authentication and authorization.
c. Which users or roles (via groups) are permitted authentication or authorization.
Programmatic
Here we make use of security methods() in built in interface HttpServletRequest.
The application(e.g. servlet) call following methods to instigate authentication from within an "unconstrained" resource.
a. request. Authenticate: A login box pops up to collect credentials.
b. request. login: This methods takes login/password without the pop
c. request. logout: Resets the user/caller identity
There are several other methods also available, that provides more details of the authenticated user like isUserInRole(whether it's in given role), GetRemoteUser(gives user name), etc.
EJB Authentication
How EJBs are authenticated??
EJBs are can also be secured in the same way, as web based apps. i.e. Either with Declarative or programmatic security. Some caveats to this statement, but those are not relevant to current discussion.
So why do we need JAAS, and what is JAAS?
To appreciate this, let's understand a practical scenario for any:
An application may have multiple authentication requirements e.g. password, certificate, authentication users from multiple security realms, perimeter authentication, etc. Do we have to code so much for every application, and type of authentication? Now, it can be cumbersome and complex create & maintain code for authenticating users based on these different techno-business requirements.
To address above situation, there has to be a Pluggable way to writing code for authentication, wherein, developers would only be responsible for mentioning(not coding) which AuthenticationProvider has to be used, and writing code to call the loginModule of that particular provider, which eventually has code to authenticate the given user/caller.
This framework of providing pluggable authentication is called Pluggable Authentication Module in LDAP world.
"JAAS" is java implementation of PAM framework. With JAAS, either updated, or additional authentication technologies can be plugged under an application, without modifying the application code as such.
After Authentication, JAAS also enforces authorization.
JEE provides libraries to implement JAAS in applications!
Is JAAS implemented in same way across different enterprise application servers like Weblogic, JBoss, etc.
Well, "It can be", "but is usually not" implemented in same way across different application servers.
This is because application server may provide its own libraries, which can be used to implement JAAS.
Hope this clarifies the JEE security model to folks who do not have development background.

Java EE Security: JASPIC / JAAS or apply a Security Framework? (Glassfish 3)

I am currently using Oracle ADF (which is an end-to-end Java EE framework) for building my web applications and GlassFish 3.1 as application server.
The latter supports JAAS (declarative inside its admin console). So, I have created a security realm and mapped them with the roles declared in a configuration file and use JAAS to implement the authorization and authentication security features.
Everything fine, until now! This past weeks I have been researching on Java EE security.
What I've found is that JAAS is good enough if you stick with "basic" security. Moreover, it seems that JAAS (as part of the Java Security Framework) was meant just for Java SE (but since Java EE is built on Java SE, some of it’s modules are being reused, such as LoginMethod and Callbacks).
Then, I've found many posts about JASPIC, finding out that it can be implemented only by a programmatic manner (not a problem) and it's not yet fully supported by app servers vendors, and tried to make a comparison between both. Even if JASPIC1.1 release had resolved some issues, like:
The container will however not fully remember the authentication. The
SAM is still called at each request, and the SAM still has to
re-authenticate
(it doesn't sound so good to me).
Then, I've passed on looking for integrating some security framework. The most famous ones seems to be "Spring" and "Shiro". Of course each one of them has it's own characteristics (may be the first is more suitable on a specific situation while the second in another). What's more important to me at the more are:
Authentication
Authorization
Session Management (and possibly, encryption)
But, everywhere I found contradictory conclusions. The result: I'm more confused now then before searching.
I am just a novice in topics like security, and moreover I am a developer (I have stuff to implement), so it's kinda hard to keep up to date with every new release and the progress on security seems to keep going on every day galloping.
I'd like some facts based on personal experience if possible. Every hint or suggestion is appreciated. I want to be sure I'm confident before taking the implementation step.
JASPIC is the one technology that being a part of Java EE integrates really well with it.
The fact that JASPIC authentication modules don't automatically remember a session is an advantage too as it makes them suitable for stateless applications too (think APIs such as JAX-RS). When you authenticate and do want sessions, then just put the result (username + groups) into the session. Then at the start of each "validateRequest" method do a quick check if there's anything in the session and if so give these to the container again. No need to authenticate from scratch and certainly no need to remember any password!
Shiro and Spring Security are very full featured frameworks. You can barely compare that to JASPIC which is very low level and basic. Both Spring and Shiro don't perfectly integrate with Java EE. Spring Security is often said to be more complex than Shiro.
Hope this helps
The Servlet profile of JASPIC requires that the configured (for the app) Server Authentication module(s) (SAM) be called on every request; exactly so that the SAM will be able to manage authentication sessions (should that be desired)
The profile also supports the case, where a SAM is configured to perform authentication, but then wishes to delegate authentication session management to the encompassing container, which is enabled by the used of the registerSession callback property.
Also as noted by Mike Braun, the profile also supports a stateless mode wrt to authentication sessions, and is fully integrated with the container authorization system; such that JASPIC authentication must occur when the target request is covered by an authorization constraint (such as would be defined in web.xml or by use of the ServletSecurity annotation).
The JASPIC defined Callbacks and the container provided Callback handler, allow a portable SAM to set the container caller principal, to consult the container's user registry for password validation and group assignment, etc.

Adding #PreAuthorize on service layer or controller layer? [duplicate]

I have been using spring security with #PreAuthorize on my controller methods. My reasoning was that I wanted the authorization check to happen predictably in one layer, and as early as possible in the request. However, I just read the spring security 3 documentation, and saw that they recommend applying method level security on the service layer (but they don't say why).
My question is: should spring security method level annotations be applied at the controller layer or the service layer? (Or "both", or "it depends"?) More importantly: why?
"It depends" :). If your application has a service layer through which all your business logic is applied then that is usually a clean place to apply your security constraints and be certain that you haven't missed out any corner cases.
Web code is generally messier, there's more of it, it changes more rapidly and you may end up calling the same service methods from multiple places. Someone might add a new controller and forget to secure it properly. Alternatively you might have different types of clients calling the same services.
But it depends on how your application is structured and what your use cases are. You may have a good argument for why you want to secure a controller.
Think in terms of code reuse. Are you going to use your service elsewhere? Not just to feed your web tier?
We also reuse our services with jms bridges so we secure our service layer.
I think the Service is the better place to use it.
Despites some problems that #PreAuthorize could create on Controller and the Spring Security FAQ recommendation to put this kind of annotation on Service, I understand that the authorization for some action is more a business rule than a responsibility for the web tier.

EJB3 & How JAAS subject/principal is propagated to EJB Tier from servlet container?

I'm trying to understand how the JAAS principal propagates to the Business/EJB tier from web tier.
I've read that the if the roles/realm is configured in login-config & security-context of web.xml then the servlet container will also transparently pass the authenticated principal to the EJB Tier.
Two questions
1.) First & more importantly is that true ? Without any intervention from the developer !
2.) And secondly any idea how that works under the hood.
yes it's true. that's generally the point of ejb, to take the "hard" stuff out of the hands of the developer (e.g. security, transactions, robustness, multithreading, etc.)
it's implementation dependent. i know that in jboss (at least 4.x and before), remote method calls used a custom serialization protocol which had an additional Map of arbitrary information which could be sent along with the request. in this was the auth info as well as other stuff to support clustering. for local method calls i believe they use stuff like ThreadLocals.
There are various "context" pieces of information that get propagated in EJB calls, once you get inside the EJB layer and start doing EJB-EJB calls then Transactions would be an example. Some containers allow you to create your own such context objects too.
Thread-local storage can be used within a process, but generally just assume that the container is in charge and can do the right thing - the actual technique is implementation specific.
Regarding your first question - yes.
Regarding your second question - are you familiar for example with EJB3 interceptors?
The container create proxied objects with "interception code" for the beans,
and in addition the container can track other annotations on the methods and the bean class, for example, to detect the #PostConstruct annotation.
Using the role definition, it can check the configuration (either login-config.xml at older versions of jboss, or standalone.xml in JBoss AS 7 at standalone configuration) and understand what is the definition per each role.
JAAS is used in order to provide you abstraction layer over authentication and authorization.
One of the concepts behind JAAS is login module - it provides you "protocol specific" code that takes care of the actual authorization and authentication.
For example, I'm using in this way Krb5LoginModule to use kerberos.
The Principal propagates to the EJB tier from web tier is configured through the login-config in the web.xml as you had surmised for the most part.
How it is implemented is implementation dependent. The user/group data is also implementation dependent and is configured as part of the application server.
However, one of they ways this is done is through an implementation of the JASPIC provider which is a standard way of obtaining the Principal. Using this allows you to have a different authentication path compared to the standard form login, basic authentication or certificate authentication provided by WEB-INF/web.xml but it is a little bit more work.
JASPIC authentication paths allow more complex scenarios such as header based authentication or two-factor or OpenID. The user database "usually" does not need to be tied to the one in the application server. I say "usually" because WebSphere Application Server ties the authentication to a user configured on the server.

Why should i use JAAS against hand-written security?

I got hand-written security, simple servlet-filter which redirect not-authorized user to their login pages. Login controller redirect them to the requested URL after successfull authentication or their main page. This approach work fine, the only disadvantage, that I have to pass User object which is stored in the HttpSession through stacktrace to EJB beans.
Now I rewrote some code and use Spring-security as http based authentication. It is integrated automatically with Glassfish JAAS.
I don't need to pass User through stacktrace anymore, invocation sessionContext.getCallerPrincipal() is enough. But the principal object return me only userName, not userId, so i have to perform addition select if i need userId for example.
1) Is there anyway to extend Principal object, so it can store more properties ?
2) Why i should use JAAS or Spring Security or another security framework, why not just hand writen servlet filter ?
2) Using a standard security mechanism like JAAS has many advantages:
You can easily change the way user authenticates solely by configuring your server - without need to change anything inside your code.
You can be sure your security is up-to-date, supporting strongest algorithms, storing Principal in a secure manner and so on. Again just by staying up-to-date with your server, framework etc. Having a hand-written security module is prone to errors and to be outdated soon.
You can leverage framework security - eg. web.xml security tags, EJB security annotations. Because JAAS is a standard way to authenticate, you can be sure adopting future technologies will be easier, because all serious technologies will support JAAS (Spring security etc.). If your software is planned to grow, you will definitely need a standard.
It will save you time and effort. JAAS provides both authentication and authorization, neatly packed and configurable within minutes.
I recommend futher reading on J2EE security or you can find more resources in OWASP guides.
1) I don't know if you can extend the class Principal. But note, in your LoginModule, before you finish the authentication calling the commit() (probably in your login() method), it is possible to add credentials in the Subject. For this, just add the object to one of the lists: Subject.getPrivateCredentials() or Subject.getPublicCredentials() (with no arguments). You can add many objects like your own class, a String, or whatever you want.
To retrieve the objects in your application, use the procedure detailed in my other answer.
import javax.security.jacc.PolicyContext;
Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");

Categories