Search code examples
javarestshiro

Securing Rest Service Resources Using Apache Shiro


I'm trying to secure my rest services written using dropwizard by Apache Shiro. First I initialized the security manager in the main method.

    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    SecurityManager securityManager = factory.getInstance();
    SecurityUtils.setSecurityManager(securityManager);

Then I wrote a service for user login.

if (!currentUser.isAuthenticated()) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        try {
            currentUser.login(token);
            System.out.println("USER AUTHENTICATED!!!!!!!!");
        } catch (Exception uae) {
            System.out.println("Error logging in .................");
        }
    }

Then I declared a method with some java annotations.

    @RequiresAuthentication 
    @RequiresRoles("admin")
    @GET
    @Path("/account")
    @ApiOperation(value = "getAccount")
    public void getAccount() {
        //do something
    }

But when I accessed this resource without logging in, I was successful.

What mistake am I doing? Or should I add something more? Like in the web.xml?


Solution

  • I found this repo very useful. https://github.com/silb/dropwizard-shiro/tree/release-0.2. I followed the instructions given in this. But there is one more thing I added in the configuration file.

    @Valid
    @JsonProperty("shiro-configuration")
    public ShiroConfiguration shiro = new ShiroConfiguration();
    

    Then in the resources class, I wrote login and logout as two services.

    @POST
    @Path("/session")
    @Produces(MediaType.TEXT_PLAIN)
    public String login(@FormParam("username") String username, @FormParam("password") String password, @Auth Subject subject) {
        subject.login(new UsernamePasswordToken(username, password));
        return username;
    }
    
    @PUT
    @Path("/logout")
    @Produces(MediaType.TEXT_PLAIN)
    public String logout(@Auth Subject subject){
        subject.logout();
        return "Successfully logged out!";
    }
    

    And then I annotated the secured resources with @RequiresAuthentication annotation.