spring-projects / spring-projects/spring-security

SEC-2220: Extending Principals and ServletApi()

Open
#2,444 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: jira
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Cemo Koc (Migrated from SEC-2220) said:

servletApi() of Spring Security is really very nice. But I am struggling with a Principal problem.

Shortly:

I would like inject my custom principal which is extending Principal to my controllers.

Details:

I have configured my Spring Security M2 perfectly. Here I have not configured anything else. Only UserDetails Service is implemented.

@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception        {
  auth
     .userDetailsService(detailsService);
}

And my usage:

public interface UserPrincipal extends Principal {
   public Integer getId();

   // and other properties...
}

@RequestMapping(value = "/")
public ResponseEntity<List<Conversation>> listAfter(UserPrincipal user){
   // implementation
}  

or


@RequestMapping(value = "/")
public ResponseEntity<List<Conversation>> listAfter(UserPrincipalImpl user){
   // implementation
}

I am expecting UserPrincipal and UserPrincipalImpl to be injected here.

But this is not possible because SecurityContextHolderAwareRequestWrapper is returning an Authentication which is delegating to internal principal.

    @Override
    public Principal getUserPrincipal() {
        Authentication auth = getAuthentication();

        if ((auth == null) || (auth.getPrincipal() == null)) {
            return null;
        }

        return auth;
    }

Problems are starting here:

  1. Having problem at injecting UserPrincipal to Controllers
        else if (Principal.class.isAssignableFrom(paramType)) {
            return request.getUserPrincipal();
        }

ServletRequestMethodArgumentResolver thinks that UserPrincipal is a Principal. This is correct. SecurityContextHolderAwareRequestWrapper#getUserPrincipal method returns Authentication which is not a UserPrincipal. This is raising an exception because it can not assign Authentication to UserPrincipal.

  1. Inevitable dependency to Spring Security because of Authentication

Consider two different modules which has the abstraction of Servlet Api. Proper implementation of this abstraction should provide no need to Spring Security.

Consider this:

Module A depends on Servlet Api and Custom Principal
Module B depends on Servlet Api and Spring Security and Custom Principal
Module Web A depends on Module A and Module B

Each module has their own Controllers. But in order to access custom principal at module A, I must be depend on Spring Security too :*( This is breaking brilliant abstraction of Spring Security and Servlet API.

And I have to use as this:

public ModelAndView someRequestHandler(Principal principal) {
   UserPrincipal activeUser = (UserPrincipal) ((Authentication) principal).getPrincipal();
   ...
}

Which is pretty ugly because I have to depend on Spring Security for module A.

My questions:

  1. Is it possible to return real Principal at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper#getUserPrincipal?
  2. If 1 is not possible, How can I configure Authentication to implement UserPrincipal methods? (This is what I really does not want)

Thanks

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading SecurityContextHolderAwareRequestWrapper#getUserPrincipal and the Principal-handling branch of ServletRequestMethodArgumentResolver. Trace how Authentication and the custom UserPrincipal types are expected to interact, then determine whether the requested controller injection is supported and what tests or documented behavior would establish a complete result.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
authentication, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.