Protecting method calls in Spring multiactionController using methodNameResolver - spring

I am using Spring 3 and implemented MVC using simpleUrlMapping. I am having CustomerController class. In CustomerController I am having three methods:
View customer
Add customer
Delete customer
The above actions are getting called using method name resolver.
My requirement over here depending upon the logged in user and privilege I want to protect the corresponding method calls.
Delete customer method should be called by the privilege user and not by all the user.
I am using Spring Security as well. Is there any way to protect the delete customer method with Spring security?

options:
#RequestMapping
public void deleteCustomer(HttpServletRequest request) {
if(request.isUserInRole("ROLE_ADMIN"){
// do deletion
};
}
or use #EnableGlobalMethodSecurity
#PreAuthorize("hasRole('ROLE_ADMIN')")
#RequestMapping
public void deleteCustomer(HttpServletRequest request) {

Related

Roles and Permission at method level Spring boot

I need to have authorization at the method level so that the users with proper permissions only can access it. The method will contain a token as a parameter. I need to make an API call passing the token and get the user email id. Once I have the email id, I need to fetch the user's roles & permissions from the database. Then I invoke the method if the user have appropriate roles else return a 403 error.
Is there a way to get this done in spring boot? I will have multiple methods behind authorization and would like to have some kind of annotation at method level.
Thanks.
#PreAuthorize annotation is what you want
Please read the following link for spring method level authorization
baeldung method authorization
you will also need to undestand SPEL(Spring Expression Language) as this is what the PreAuthorize method gets as parameter , link can be found here
please note that spring uses the SecurityContext to get the user data(Role etc..), meaning that the user already passed the login(authentication) stage and has SecurityContext loaded for said user
Example:
//other annotations
#PreAuthorize("hasRole('ROLE_VIEWER')") // hasRole('ROLE_VIEWER') -> this is SPEL
public ResponseEntity<String> methodName() {
//method
}
You can use #PreAuthorize with more flex as:-
#PreAuthorize("#securityService.hasPermission({'PERMISSION_1'})")
and service:-
#Component("securityService")
public class SecurityService {
public boolean hasPermission(PermissionEnum... permissions) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication()
.getAuthorities();
for (PermissionEnum permission : permissions) {
if (authorities.contains(new SimpleGrantedAuthority(permission.toString))) {
return true;
}
}
return false;
}
}
You can make it as you want.
For more
https://dreamix.eu/blog/java/implementing-custom-authorization-function-for-springs-pre-and-post-annotations
https://try2explore.com/questions/10125443

How to retrive logged in user data in spring mvc and hibernate

I need to get current loggedin user's details along entertain session.Is there any poissible to do it in Spring and hibernate
I am new to spring and hibernate...Help me guys.
There are serveral ways in which you can accomplish this. In a controller you can inject a Pricipal as a parameter.
#RequestMapping()
public void getPricipal(Principal principal) {
Customer c = (Customer) pricipal;
}
You should also be able to inject the UserDetails directly as well. Spring will resolve it for you. Your Customer class must implement UserDetails
#RequestMapping()
public void getPricipal(Customer customer) {
}
As for having all details, you should be able to access the firstname, lastname etc, if you've implemented your own UserDetailsService where you return your custom UserDetails (Customer).

Spring REST design public and authenticated API

I'm trying to design an application that should expose two global API path:
/ user must be authenticated
/public no authentication
Moreover /public API will offer light version of some / API by displaying less informations that is not authorize if no authentication is provided.
Even if Controller does not contains core function, some of them provide data validation or other check. Thus if I want to create a /public version of a current API I have 4 solutions:
Duplicate code
#Autowired / controller and use method call
forward request (I can't redirect because security filter will be applied)
Create Controller that manage both / and /public API
Is there any good practice or pattern for my scenario?
IMHO, Best way to solve this problem is by using 4th solution.
1st solution: First rule of computer science is you do not duplicate your code.
2nd solution: calling controller from another controller is a serious design flaw.
3rd solution: could have been a solution but ruled out by you.
4th solution: IMHO best one in your case
class MyController{
#RequestMapping("/getData")
public ResponseObject getData(#RequestBody SomeDTO dto){
Validator.validate(dto);
return myService.getData(dto);
}
#RequestMapping("/public/getData")
public ResponseObject getPublicData(#RequestBody SomeDTO dto){
Validator.validate(dto);
return myService.getPublicData(dto);
}
}
Filter data in your service layer.
It's possible to be achieved with Spring Security.
First, you will need to enable this URL to be called without security, like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
/** some security code **/
http
.authorizeRequests().antMatchers("/resources/**","/public/**").permitAll().anyRequest().authenticated().and()
/** other stuffs **/
}
#RestController
#RequestMapping(value="/public")
public class PublicRestController {
#Autowired private DataRepository data;
#RequestMapping(value = "/data/",method = RequestMethod.GET)
public Model getModelData(){
/** Do what you need here **/
}
}
So, all you have to do is build a REST Controller to match your URL and you are done.
And as you suggested, use #Autowired to expose only the code that you need. So you can put all your login on service/component beans and serve them as needed.

Session based validation in ServiceStack

I have some validation logic, which is based a user's session.
Сan I access the session from a class inherited from AbstractValidator?
Or is there another way to check RequestDTO based session?
For example I can use filters for that (and I can access the session via IRequest parameter req in overrided Execute method), but I don't know how to return the response from the class of the filter, bypassing the main method of the operation. If I will throw the Exception, the service will not work properly because RequestDTO declared outside of my project and it is not inherited from IReturn<> and does not contain a ResponseStatus field.
Thanks in advance for any help (and sorry for my English)
If your validator implements IRequiresRequest then it will injected with the current IRequest which you can use in your lambda expressions, e.g:
public class CustomValidator : AbstractValidator<Request>, IRequiresRequest
{
public IRequest Request { get; set; }
...
}

Spring JSF application flow

I have previously written Spring MVC web applications where there is a front controller and we have a request mapping in each of the methods and this method in turn invokes a service implementation finally returning a view to the UI. Now when I design JSF applications am not able to understand the flow as such -
This is what I currently have in my application:
The initial index.html redirects to the login page.
A backing bean for the login page which populates label values. Since it is an input form there is no other logic involved.
Once the user clicks on submit -> in the action method I have logic which will invoke the service(No.1) for authentication process and redirect the user to the home page by returning the name of the page
The home page displays various fields which are bound to a backing bean whose fields have to be populated by another web service call(No.2).
It is between the steps (3) and (4), I have a confusion. Previously in Spring I had an explicit mapping and I can "actually" control the logic in the front controller method. In JSF, I dont know whether the logic for No.2 web service call should be combined along with authentication call since I dont have a method to populate the beans.
It is as if I dont have the explicit control over the flow. I have read many articles trying to understand this but not am able to understand. Please provide me pointers and also some references which will actually explain this better.
Why can't you control the logic in JSF bean?Example usage with EJB
#ManagedBean
#RequestScoped
public class LoginBean {
#EJB
private AuthBean authBean;
#EJB
private UserSettings settingsBean;
private String name, password;
#PostConstruct
private void init() {
//do your initialization here
}
public String loginAction() {
User user = authBean.authenticate(user, password);
if(user != null) {
UserSetting settings = settingsBean.getSettings(user.getId());
return "home";
}
}
//setters and getters
}

Resources