dead programmer
dead programmer

Reputation: 4365

@Secured is not working while integrating Spring Security in Jersey project

I have a demo JAX-RS project using Jersey. Now I am trying add Spring Security's method level security but unfortunately its not working although intercept-url xml way is working fine.

  1. Added all the dependency in my pom.xml
  2. Updating web.xml as

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
        /WEB-INF/security.xml,
        /WEB-INF/beans.xml
    </param-value>
    </context-param>
    <!-- this is default security impl name used by deletetingFiterProxy -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  3. Updating /WEB-INF/security.xml

    <beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">
        <!-- kind of authentication applied 1) Basic 2) form-based etc.. auto-config="true" use-expressions="true"-->
        <http  auto-config="true">
            <http-basic />
        </http>
    
        <!-- this allow to enable security annotations in restful resoruces -->
        <global-method-security secured-annotations="enabled"  />
    
        <!-- for defining users and roles -->
        <authentication-manager>
            <authentication-provider>
                <user-service>
                    <user name="admin" password="admin" authorities="ROLE_CUSTOMER,ROLE_ADMIN"/>
                    <user name="student" password="student" authorities="ROLE_CUSTOMER"/>
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </beans:beans>
    
  4. Annotating service inteface methods

    public interface StudentServiceInterface {
    
        @GET
        @Path("/students")
        @Secured("ROLE_CUSTOMER")
        public Response getStudents();
    
        @GET
        @Path("/students/{id}")
        @Secured("ROLE_CUSTOMER")
        public Response getStudent(@PathParam("id") int id);
    
        @POST
        @Path("/students")
        @Consumes(MediaType.APPLICATION_JSON)
        @Secured("ROLE_ADMIN")
        public Response addStudent(Student stu);
    }
    

Now when I try to access the resource student (/student) class it opens without asking password.

http://localhost:3126/securitydemo/webapi/db/students

StudentServiceInterface interface implementation

@Path("/db")
@Produces(MediaType.APPLICATION_JSON)
public class StudentService implements StudentServiceInterface{

    static StudentDao data= new StudentDaoImpl();

    @Override
    public Response getStudents(){
        GenericEntity<List<Student>> entity = new GenericEntity<List<Student>>(data.getAllStudents()){};
        return  Response.ok(entity).build();
    }

    @Override
    public Response getStudent(@PathParam("id") int id){
        return  Response.ok(data.getStudent(id)).build();
    }


    @Override
    public Response addStudent(Student stu) {
        data.addStudent(stu);
        return Response.ok(stu).build();
    }

}

Upvotes: 0

Views: 284

Answers (1)

dur
dur

Reputation: 16969

You have to use the extention for Spring DI, see Jersey 2.25.1 User Guide:

Jersey provides an extension to support Spring DI. This enables Jersey to use Spring beans as JAX-RS components (e.g. resources and providers) and also allows Spring to inject into Jersey managed components.

The Spring extension module configuration is based on annotations. Spring beans are injected and JAX-RS classes are made Spring managed using annotations. Injected Spring beans can have further dependencies injected using Spring XML configuration. Spring singleton and request scopes are supported.

To enable JAX-RS resources to work Spring functionality that requires proxying, such as Spring transaction management (with @Transactional), Spring Security and aspect oriented programming (such as @Aspect), the resources must themselves be managed by Spring, by annotating with @Component, @Service, @Controller or @Repository:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.springframework.stereotype.Component;

@Component
@Path("/")
public class SomeResource {

    @Transactional
    @GET
    public void updateResource() {
        // ...
    }
}

Limitations:

Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration

25.1. Dependencies

If you want to use Jersey Spring DI support you will need to add the jersey-spring3 module into the list of your dependencies:

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>2.25.1</version>
</dependency>

The above module adds transitive dependencies on Spring modules. See jersey-spring3 module dependencies for more details about list and scope of dependencies. Please note the module depends on The Spring/HK2 Bridge that is used to inject Spring services into HK2 services or inject HK2 services into Spring services.

Upvotes: 1

Related Questions