测试 Jersey AuthenticationFilter
不使用密码和使用密码分别访问 : http://localhost:8080/JerseyDemos/rest/employees
使用ResourceConfig注册AuthenticationFilter
现在你需要使用 ResourceConfig实例注册上面的过滤器。
所以创建一个如下所示的实例:
package com.onitroad.jersey;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import com.onitroad.jersey.provider.AuthenticationFilter;
import com.onitroad.jersey.provider.GsonMessageBodyHandler;
public class CustomApplication extends ResourceConfig
{
public CustomApplication()
{
packages("com.onitroad.jersey");
register(LoggingFilter.class);
register(GsonMessageBodyHandler.class);
//Register Auth Filter here
register(AuthenticationFilter.class);
}
}
并在 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>Archetype Created Web Application</display-name> <servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.onitroad.jersey.CustomApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
之路教程 https://onitr oad .com
保护 REST API
使用标准的 JAX-RS 注释,如下所示。
@Path("/employees")
public class JerseyService
{
@RolesAllowed("ADMIN")
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Employees getAllEmployees()
{
Employees list = new Employees();
list.setEmployeeList(new ArrayList<Employee>());
list.getEmployeeList().add(new Employee(1, "JackLi Gupta"));
list.getEmployeeList().add(new Employee(2, "JackLi Kolenchiskey"));
list.getEmployeeList().add(new Employee(3, "Tomm Kameron"));
return list;
}
}
使用基本身份验证保护 Jersey REST API。
这将强制每个用户提供用户名/密码以进行门户身份验证。
此外,用户还必须具有一定级别的角色。
这里使用 ContainerRequestFilter 实现来验证用户在登陆实际 REST API 之前的访问权限。
创建请求认证过滤器
我们知道 JAX-RS 2.0 具有用于处理请求前后的过滤器,因此我们将使用 ContainerRequestFilter接口。
在此过滤器中,我们将获得请求尝试访问的方法的详细信息。
我们将找出该方法的所有安全相关配置,并验证此过滤器中的所有内容,例如像@PermitAll、@DenyAll或者@RolesAllowed这样的注释。
根据应用在方法上的注解,我们将决定通过或者阻止请求。
package com.onitroad.jersey.provider;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.internal.util.Base64;
/**
* This filter verify the access permissions for a user
* based on username and passowrd provided in request
* */
@Provider
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter
{
@Context
private ResourceInfo resourceInfo;
private static final String AUTHORIZATION_PROPERTY = "Authorization";
private static final String AUTHENTICATION_SCHEME = "Basic";
@Override
public void filter(ContainerRequestContext requestContext)
{
Method method = resourceInfo.getResourceMethod();
//Access allowed for all
if( ! method.isAnnotationPresent(PermitAll.class))
{
//Access denied for all
if(method.isAnnotationPresent(DenyAll.class))
{
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN)
.entity("Access blocked for all users !!").build(););
return;
}
//Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
//Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
//If no authorization information present; block access
if(authorization == null || authorization.isEmpty())
{
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)
.entity("You cannot access this resource").build());
return;
}
//Get encoded username and password
final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
//Decode username and password
String usernameAndPassword = new String(Base64.decode(encodedUserPassword.getBytes()));;
//Split username and password tokens
final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
final String username = tokenizer.nextToken();
final String password = tokenizer.nextToken();
//Verifying Username and password
System.out.println(username);
System.out.println(password);
//Verify user access
if(method.isAnnotationPresent(RolesAllowed.class))
{
RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
//Is user valid?
if( ! isUserAllowed(username, password, rolesSet))
{
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)
.entity("You cannot access this resource").build(););
return;
}
}
}
}
private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet)
{
boolean isAllowed = false;
//Step 1. Fetch password from database and match with password in argument
//If both match then get the defined role for user from database and continue; else return isAllowed [false]
//Access the database and do this part yourself
//String userRole = userMgr.getUserRole(username);
if(username.equals("onitroad") && password.equals("password"))
{
String userRole = "ADMIN";
//Step 2. Verify user role
if(rolesSet.contains(userRole))
{
isAllowed = true;
}
}
return isAllowed;
}
}
日期:2020-09-17 00:16:33 来源:oir作者:oir
