0

I need to provide role based access for my REST APIs and I have seen that we could use @PreAuthorize, @Secured for this. However I am not sure as to what changes should I make and get this in place as currently I use a custom token based authentication mechanism generate a token for a session and handle it myself.

 @RequestMapping(value = "login", method = RequestMethod.POST) public @ResponseBody Result login(@RequestBody Credentials credentials) { return loginService.login(credentials.getUsername(), credentials.getPassword()); } 

The Result class just contains a generated token for the user which he will be passing on each request.

Now any idea what changes should I make to restrict the access of an API if the user is in particular role

For example if I want to restrict the API findById to be accessed by user only if he is part of ADMIN_ROLE then I will have to add the PreAuthorize annotation but am not sure how will this determine the user role and block the user automatically.

@PreAuthorize("ADMIN_ROLE") @RequestMapping(value = "{id}", method = RequestMethod.GET) public @ResponseBody Group findById(@PathVariable int id) { return groupParser.getGroupById(id, groupService.getGroupTree()); } 
3
  • I handle a custom token based authentication @RequestMapping(value = "login", method = RequestMethod.POST) public @ResponseBody Result login(@RequestBody Credentials credentials) { return loginService.login(credentials.getUsername(),credentials.getPassword()); } Commented Mar 26, 2016 at 13:46
  • please, instead of explaining the configuration, post it :-) You'll have much more precise answer if you d so. Commented Mar 27, 2016 at 12:32
  • Thanks @StefanoCazzola . I have made some changes and have added some more information. Commented Mar 28, 2016 at 5:47

1 Answer 1

1

What you need to do is to tweak Spring Security configuration. Below an example with XML config (I'm much more used to it); however, it is doable also in JavaConfig.

Basically, Spring security is fired by the

<http ....> ... </http> 

element. You'll need to write it like that (or something like that)

<beans:bean id="authenticatedVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"> <beans:property name="expressionHandler" ref="..." /> </beans:bean> <beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"> <beans:property name="rolePrefix" value="" /> <!-- if you want to customize role prefix --> </beans:bean> <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> <beans:constructor-arg> <beans:list> <beans:ref bean="roleVoter" /> <beans:ref bean="authenticatedVoter" /> </beans:list> </beans:constructor-arg> </beans:bean> <!-- use-expressions enables the @PreAuthorize --> <http use-expressions="true" access-decision-manager-ref="accessDecisionManager"> .... </http> 

Note the beans added: they are three Spring components.

The first holds an unspecified reference. It expects something implementing SecurityExpressionHandler: in your case you'll have to provide a DefaultMethodSecurityExpressionHandler

Then, to add your custom token configuration, you'll need to write a filter of your own and wire it into the HTTP element. You can do it quite easily by extending Spring classes and then customizing its behaviour

public class MyClientAuthenticationFilter extends OncePerRequestFilter { .... @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // custom logics here // throw exception for not authenticated } } 

and then wire it up

<bean class="x.y.z.MyClientAuthenticationFilter" id="myClientAuthenticationFilter" /> <http ....> <custom-filter ref="myClientAuthenticationFilter" before="BASIC_AUTH_FILTER" /> </http> 

You should be basically done.

Just remember to include spring-security-aspects in your build: Spring security @PreAuthorize and other annotations are intercepted via AOP, hence you'll need to provide these aspects in your classpath.

Also, keep in mind that this is not the full configuration: it would take a very long post to wire everything up: it is jut an example about how to start.

For deeper infos, rely on Spring Security documentation itself.

Last note: if you're using JvaConfig instead of XML, there should be annotations that can rid you of part of thi config, but the custom filter.

Hope it helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Stefano for the hint. I setup the java config environment exactly based on your xml config and integrated the spring security features for my application. One more thing I did is that I added a filter in my application which adds an authentication in the SecurityContextHolder.getContext as I used token based authentication and for the next call the state is lost and I need to rebuild the state so that @PreAuthorize works fine.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.