My security config class (which inherits from WebSecurityConfigurerAdapter) has a method like the following.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/restaurant/**").access("hasRole('ROLE_USER')")
.and()
.formLogin();
}
However I'd rather use #PreAuthorize on my controllers instead. If I remove the method everything requires auth. What should my method look like so everything is available and access is only determined by PreAuthorize?
As has been already stated, it is not very common to use method level security to secure controller methods but rather to secure methods with business logic. And even if you need to perform authorization based on request attributes, it should be possible to achieve this with URL based security and web security expressions.
Available expressions are defined by WebSecurityExpressionRoot class, an instance of which is used as the expression root object when evaluation web-access expressions. This object also directly exposed the HttpServletRequest object under the name request so you can invoke the request directly in an expression.
Here you can find more details on when to use URL based security and when method level security.
It is rather uncommon to use #PreAuthorize on controller methods, but there may me use cases, if the decision depends on request parameters ...
If you do not want to do any authorization at the request level, you can simply have :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin();
}
You only declare a form login, and no request security. But do not forget that request security uses less resources than method security.
Instead of .access("hasRole('ROLE_USER')"), try .access("permitAll"). Note that for request mappings that doesn't have a #PreAuthorize, everyone will be given access.
Related
Can you please explain in a simple way for what reason we need to use and() method in HttpSecurity.
Code:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").hasAnyRole("Employee", "Manager", "HR")
.antMatchers("/hr_info").hasRole("HR")
.antMatchers("/manager_info/**").hasRole("Manager")
.and().formLogin().permitAll();
}
The spring security reference explains it as follows.
The Java Configuration equivalent of closing an XML tag is expressed
using the and() method which allows us to continue configuring the
parent. If you read the code it also makes sense. I want to configure
authorized requests and configure form login and configure HTTP Basic
authentication.
Accordingly, you say the following with your own settings:
Ensures that any request to our application requires the user to be authenticated,
Allows authentication for some links only to the specified role,
Allows users to authenticate with form based login.
In the below code what do the different chained methods do?
protected void configure(HttpSecurity http ) throws Exception {
http.authorizeRequests()
.antMatchers(PUBLIC_URL).permitAll()
.anyRequest().authenticated();
}
NOTE: PUBLIC_URL is an array of strings containing public URLs.
authorizeRequests() Allows restricting access based upon the HttpServletRequest using RequestMatcher implementations.
permitAll() This will allow the public access that is anyone can access endpoint PUBLIC_URL without authentication.
anyRequest().authenticated() will restrict the access for any other endpoint other than PUBLIC_URL, and the user must be authenticated.
We can also configure access based on authorities, can manage the sessions, HTTPS channel and much more. You may find more details from configure(HttpSecurity http).
It means that all requests must be authenticated except those matching PUBLIC_URL
I have a REST API written in Spring Boot with Spring Security and OAuth2. The resources are secured this way:
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/v1/security/**").hasRole("ADMIN");
}
I'd like to introduce a new part of the API where the permissions are fine grained, based on projects. Let's consider a simple endpoint that prints the project configuration.
GET /api/v1/project/{projectId}/config
How would I configure the resource server to only allow access for users who have the role ROLE_PROJECT_{projectId}_ADMIN without having to manually specify all projects?
Also if this mechanism has a specific name, please let me know in comments to I can change the question title.
You can use path values in authorization expressions.
According to Path Variables in Web Security Expressions you should write your custom authorization logic.
public class WebSecurity {
public boolean checkUserHasAccessToProjectId(Authentication authentication, int projectId) {
// here you can check if the user has the correct role
// or implement more complex and custom authorization logic if necessary
}
}
Then in your Java security configuration you can refer to this method and pass it the value of the relevant path fragment.
http.authorizeRequests()
.antMatchers("/api/v1/project/{projectId}/config")
.access("#webSecurity.checkUserHasAccessToProjectId(authentication,#projectId)")
...
I'm using Spring Boot to create my microservices and I'm enabling the OAuth2 to add security to my services.
However, there are some methods that I can not understand what are the differences between then. For example, I have the following code:
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(STATELESS);
http.authorizeRequests()
.antMatchers(POST, "/v1/files/").access("#oauth2.clientHasRole('ROLE_CLIENT')");
}
In this example, I used the access method to check if the system that is going to access my services has the ROLE_CLIENT role.
The question is : what are the main differences between the following methods:
hasRole
hasAuthority
access
hasRole(NAME) checks that client has ROLE_NAME whether hasAuthority(NAME) checks only NAME role.
hasRole("CLIENT") is equivalent to hasAuthority("ROLE_CLIENT")
I am using Spring-security in a Spring-boot appplication. By default, all methods are restricted to authenticated users thanks to this configuration :
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
Now, I would like to mark some urls as public. I could do it with ant matchers but I would prefer to be able to directly mark the relevant methods with an annotation.
I saw that some #PreAuthorize annotation exist but I could have it work only if I remove those lines from the configuration :
.authorizeRequests()
.anyRequest().authenticated()
This forces me to annotate manually every method that I want to secure with this annotation :
#PreAuthorize("isAuthenticated()")
This is highly dangerous because every forgotten url will be publicly accessible by default. Is there a way to make every url accessible to authenticated users by default and open some urls with
#PreAuthorize("permitAll()")
Also, I saw in another post that the OP was answered :
But it is really a bad idea to use pre-post annotation on a controller, for what could be done directly in HttpSecurity configuration. It forced you to use proxyTargetClass = true.
What is wrong with that? (Also, I did not need to use proxyTargetClass = true)