I want to secure my jersey JAX-RS services with Apache Shiro security with out JSP but its not working.
when i use browser to test my services the server redirect me to login page as expected and when i insert username and password and then press submit button the server does not redirect me back to the service after login.
i am getting this Error: HTTP ERROR 404 Problem accessing /rest/hello/some_text. Reason: Not Found Powered by Jetty://
the code I working on it can be download from here https://github.com/javajack/shiro-jersey.git and look for sub project "jersey-sample" i only modified the shiro.ini and change the: "authcBasic" to "authc".
i test it with my browser: url: localhost:port/rest/hello/some_text
what am i missing ?
the following is my configuration:
shiro.ini:
[main]
authc.loginUrl = /connect.html
[users]
root = secret,admin
guest = guest,guest
presidentskroob = 12345,president
darkhelmet = ludicrousspeed,darklord,schwartz
lonestarr = vespa,goodguy,schwartz
[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5
[urls]
/connect.html = authc
/rest/** = authc
web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>rest web application JAX-RS with Security Framework</display-name>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.apache.shiro.jersey.sample</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>org.apache.shiro.jersey.ShiroResourceFilterFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
AdminSecretsResource.java
package org.apache.shiro.jersey.sample;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.apache.shiro.authz.annotation.RequiresRoles;
@Path("/admin")
@RequiresRoles("admin")
public class AdminSecretsResource {
@GET
public Response tellSecret() {
final String output = "Shh, the secret answer is 41.";
return Response.status(200).entity(output).build();
}
}
HelloWorldResource .java
package org.apache.shiro.jersey.sample;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@Path("/hello")
public class HelloWorldResource {
@GET
@Path("/{message}")
public Response sayHello(@PathParam("message") String message) {
String output = "Jersey says : " + message;
return Response.status(200).entity(output).build();
}
}
connect.html
<!DOCTYPE html>
<html>
<head>
<title>Apache Shiro Tutorial Webapp : Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.min.css">
<style> body{padding-top:20px;} </style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Please sign in</h3>
</div>
<div class="panel-body">
<form name="loginform" action="" method="POST" accept-charset="UTF-8" role="form">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="Username or Email" name="username" type="text">
</div>
<div class="form-group">
<input class="form-control" placeholder="Password" name="password" type="password" value="">
</div>
<div class="checkbox">
<label>
<input name="rememberMe" type="checkbox" value="true"> Remember Me
</label>
</div>
<input class="btn btn-lg btn-success btn-block" type="submit" value="Login">
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
</body>
</html>
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.apache.shiro.jersey</groupId>
<artifactId>shiro-jersey-root</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.shiro</groupId>
<artifactId>jersey-sample</artifactId>
<name>Apache Shiro :: Samples :: Jersey</name>
<version>1.0.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>[1.2.1,2.0.0)</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>[1.2.1,2.0.0)</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-jersey</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>[1.10,2.0)</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>[1.10,2.0)</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>never</forkMode>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<contextPath>/</contextPath>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>9080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<requestLog implementation="org.mortbay.jetty.NCSARequestLog">
<filename>./target/yyyy_mm_dd.request.log</filename>
<retainDays>90</retainDays>
<append>true</append>
<extended>false</extended>
<logTimeZone>GMT</logTimeZone>
</requestLog>
</configuration>
</plugin>
</plugins>
</build>
</project>
Update your shiro.ini configuration file to add the login page to the form authentication filter as below:
shiro.ini:
[urls]
/connect.html = authc
/rest/** = authc
This would say to the Shiro engine to process any request along with the authentication request (/connect.html) using the FormAuthenticationFilter. Those paths are complementory and should be both specified to work correctly.