java中如何对受限资源进行身份验证和授权

java中如何对受限资源进行身份验证和授权,java,angularjs,jersey,jersey-2.0,Java,Angularjs,Jersey,Jersey 2.0,我有一个web.xml文件,它限制REST api使用url/rs/private/*/,如下所示: <security-constraint> <web-resource-collection> <web-resource-name>PRIVATE REST API</web-resource-name> <url-pattern>/rs/private/*</ur

我有一个web.xml文件,它限制REST api使用url
/rs/private/*/
,如下所示:

<security-constraint>
        <web-resource-collection>
            <web-resource-name>PRIVATE REST API</web-resource-name>
            <url-pattern>/rs/private/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>HEAD</http-method>
            <http-method>PUT</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description>Have to be a USER</description>
            <role-name>USERS</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>userauth</realm-name>
    </login-config>
    <security-role>
        <description/>
        <role-name>USERS</role-name>
    </security-role>
firefox中的请求标头:

Accept  
application/json, text/plain, */*
Accept-Encoding 
gzip, deflate
Accept-Language 
en-US,en;q=0.5
Authorization   
Bearer eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcnRoLmNvbSIsInN1YiI6IlJUSCIsImV4cCI6MTQ1Mjk3Nzc4NiwiZW1haWwiOiJraXJpdGkuazk5OUBnbWFpbC5jb20ifQ
.SwyVMdweHgH3eQ-IYDUsjavAbUYPWQTSvdrIKMVQEzDTIsgvpWsoR13SJsV6kHrC_2uelBG0aSgExj794xe5yrK7VQ8J4yPRrXT
1EPf4LyABuHltHJNVtR_PRpPxcLZnP4GAQm-ozBVyHarsCpI9FINwhepY4_Lt51lU_EtDjI4
Host    
localhost:7070
Referer 
http://localhost:7070/RTH_Sample13/
User-Agent  
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
问题是,当我用java打印请求头时,我找不到从以下地址发送的授权头:

@Path("/public/loginResource")
public class LoginService {

    @Context
    private UriInfo context;

    public LoginService() {
    }

    @POST
    @Path("/login")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response authenticateUser(@Context HttpServletRequest request, Credentials credentials) {

        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = (String) headerNames.nextElement();
            System.out.println(headerName);

            //PRINTS: host user-agent accept accept-language accept-encoding content-type referer content-length connection

        }
        String email = credentials.getEmail();
        String password = credentials.getPassword();
        String token = "";

        try {
            LoginDAO loginDao = new LoginDAO();
            if (loginDao.authenticate(email, password)) {
                TokenProvider jwtProvider = new TokenProvider();
                token = jwtProvider.getToken(email);
                Map<String, String> response = new HashMap<String, String>();
                response.put("token", token);
                return Response.ok(response).build();
            } else {
                return Response.status(Response.Status.UNAUTHORIZED).type("text/plain").entity("Invalid Username or Password!").build();
            }

        } catch (Exception e) {
            e.printStackTrace();
            return Response.status(Response.Status.NOT_FOUND).type("text/plain").entity("Error in Login Service web service class").build();
        }
    }
}
@Path(“/public/loginResource”)
公共类登录服务{
@上下文
私有信息上下文;
公共登录服务(){
}
@职位
@路径(“/login”)
@产生(MediaType.APPLICATION_JSON)
@使用(MediaType.APPLICATION_JSON)
公共响应认证器(@Context-HttpServletRequest-request,Credentials){
枚举headerNames=request.getHeaderNames();
while(headerNames.hasMoreElements()){
字符串headerName=(字符串)headerName.nextElement();
系统输出打印名(headerName);
//打印:主机用户代理接受接受语言接受编码内容类型引用器内容长度连接
}
字符串email=credentials.getEmail();
字符串密码=凭据。getPassword();
字符串标记=”;
试一试{
LoginDAO LoginDAO=新LoginDAO();
if(登录验证(电子邮件、密码)){
TokenProvider jwtProvider=新的TokenProvider();
token=jwtProvider.getToken(电子邮件);
Map response=newhashmap();
response.put(“token”,token);
返回Response.ok(Response.build();
}否则{
返回Response.status(Response.status.UNAUTHORIZED)。键入(“text/plain”).entity(“无效的用户名或密码!”).build();
}
}捕获(例外e){
e、 printStackTrace();
返回Response.status(Response.status.NOT_FOUND)。键入(“text/plain”).entity(“登录服务web服务类中的错误”).build();
}
}
}
我想要实现的是截获每个请求,并使用授权头和使用某种过滤器的令牌识别用户

这里有两个问题:

  • 请求标头不包含
    授权
    标头
  • 如何在java中拦截每个请求
  • 评论太长了


    至于你的第一个问题,我没有使用
    angularjs
    ,而是使用纯
    js
    ,看看我的代码,我会写
    'Basic'+store.get('jwt')
    ,而不是
    'Bearer'+store.get('jwt')

    至于你的第二个问题,确实和其他评论一样,关于jersey身份验证过滤器的问题很多。这很简单,你可以看一看

    但是,如果您想手动执行此操作,则必须在每个服务中执行此操作。(我真的不明白为什么添加过滤器会成为一个问题,但无论如何)

    它是这样的(实际上,与您在过滤器中所做的相同):

    @GET
    @产生(MediaType.APPLICATION_JSON)
    公共yourService(@Context final ContainerRequestContext requestContext){
    字符串身份验证=requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
    if(!authentication.startsWith(“Basic”)){
    抛出新的(“未认证”);
    }
    authentication=authentication.substring(“Basic”.length());
    字符串[]值=Base64.decodeAString(身份验证).split(“:”);
    如果(值。长度<2){
    抛出新的(“用户名和密码的语法无效”);
    }
    ...
    
    然后,您将对照ddbb或任何您必须存储的用户和密码进行检查

    当然,您需要将其放在实用方法或类似的东西中

    最后,如果您使用CORS,您必须小心,根据您的客户端,您可能会有一个标题为空的
    飞行前
    请求。不知道
    angularjs
    是否执行此操作。请告诉我


    希望有帮助!

    关于第二个问题,jersey有过滤器可以做到这一点。至于你的第一个问题,我不使用
    angularjs
    ,而是使用纯
    js
    ,看看我的代码,我会写
    'Basic'+store.get('jwt')
    而不是
    'Bearer'+store.get('jwt'))
    。至于你的第二个问题,确实有很多关于
    jersey
    身份验证过滤器的问题。看一看,例如……希望如此helps@lrnzcigjersey身份验证过滤器使用jersey 2.0,配置2.0 JAR和所有内容都很麻烦。还有其他选择吗?当然可以在Satyadev完成,但我不建议修复它。我将添加一个答案,给我15分钟。我尝试使用jersey server 2.0 jar和jersey servlet container 2.0 jar使用
    ContainerRequestContext
    ,但有太多错误,无法识别restwebservice类。我还添加了
    org.glassfish.jersey.servlet.ServletContainer
    jersey.config.server.provider.packages
    到web.xml文件,但仍然无法运行应用程序:(您如何部署您的服务器?在netbeans中使用netbeans 8.02与jee7和apacheTomcat 8是否使用maven?不,我没有使用maven..手动添加JAR。
    @Path("/public/loginResource")
    public class LoginService {
    
        @Context
        private UriInfo context;
    
        public LoginService() {
        }
    
        @POST
        @Path("/login")
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_JSON)
        public Response authenticateUser(@Context HttpServletRequest request, Credentials credentials) {
    
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = (String) headerNames.nextElement();
                System.out.println(headerName);
    
                //PRINTS: host user-agent accept accept-language accept-encoding content-type referer content-length connection
    
            }
            String email = credentials.getEmail();
            String password = credentials.getPassword();
            String token = "";
    
            try {
                LoginDAO loginDao = new LoginDAO();
                if (loginDao.authenticate(email, password)) {
                    TokenProvider jwtProvider = new TokenProvider();
                    token = jwtProvider.getToken(email);
                    Map<String, String> response = new HashMap<String, String>();
                    response.put("token", token);
                    return Response.ok(response).build();
                } else {
                    return Response.status(Response.Status.UNAUTHORIZED).type("text/plain").entity("Invalid Username or Password!").build();
                }
    
            } catch (Exception e) {
                e.printStackTrace();
                return Response.status(Response.Status.NOT_FOUND).type("text/plain").entity("Error in Login Service web service class").build();
            }
        }
    }
    
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public <your_output_class> yourService(@Context final ContainerRequestContext requestContext) {
    
        String authentication = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
        if (! authentication.startsWith("Basic ")) {
            throw new <your_exception>("Not authenticated");
        }
        authentication = authentication.substring("Basic ".length());
        String[] values = Base64.decodeAsString(authentication).split(":");
        if (values.length < 2) {
            throw new <your_exception>("Invalid syntax for username and password");
        }
        ...