当前位置: 首页 > 知识库问答 >
问题:

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

邵研
2023-03-14

我有我的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>

从angular开始,我在授权http报头中发送承载令牌:

$httpProvider.interceptors.push(['$q', '$location', 'store', function ($q, $location, store) {
            return {
                'request': function (config) {
                    config.headers = config.headers || {};
                    if (store.get('jwt')) {
                        config.headers.Authorization = 'Bearer ' + store.get('jwt');
                    }
                    return config;
                },
                'responseError': function (response) {
                    if (response.status === 401 || response.status === 403) {
                        $location.path('/Login');
                    }
                    return $q.reject(response);
                }
            };
        }]);

火狐中的请求标头:

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打印请求头时,我找不到angular发送的授权头:

@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();
        }
    }
}

我想实现的是,我想拦截每一个请求,并使用某种过滤器使用授权头和令牌来识别用户。

这里有两个问题:

    < li >请求标头不包含< code >授权标头 < li >如何在java中拦截每个请求

共有1个答案

唐兴思
2023-03-14

评论太长了。

至于你的第一个问题,我没有使用< code>angularjs,而是使用纯< code>js,查看我的代码,我将编写< code > ' Basic ' store . get(' jwt ')而不是< code > ' Bearer ' store . get(' jwt ')。

至于你的第二个问题,事实上,和其他评论一样,关于jersey身份验证过滤器有很多问题。这是非常直接的,你可以在这里看看。

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

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

@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");
    }
    ...

然后,您将对照ddbb或任何存储用户和密码的东西进行检查。

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

最后,如果您使用CORS,您必须小心,根据您的客户,您可能有一个标题为空的< code>preflight请求。不知道< code>angularjs是否会这样做。只是让我知道。

希望它有帮助!

 类似资料:
  • 我开发了夸库斯应用程序。我正在尝试通过LDAP服务器对Rest调用的endpoint进行身份验证。要求是,如果用户想要访问endpoint之前,它通过Active Directory对用户所属的组织进行身份验证。如果他属于并获得成功,那么它应该为用户授权。 有谁能帮上忙吗?Quarkus在Java的应用如何进行认证。 我已经介绍了https://quarkus.io/guides/security

  • 问题内容: 我相信我可以使用基本身份验证,但是我不确定如何保护资源,以便仅在用户登录时才能访问它们。 我的登录资源是这样的: 我用以下方式签署用户: 题 假设用户使用端点从浏览器或本机移动应用程序前端登录。那么如何我可以保护另一个端点,比方说,它 要求用户要signedin 问题答案: 尝试实现REST时有两件事。一个是身份验证(似乎已经可以使用),另一个是授权(我相信您的问题是)。 我之前在dr

  • 我有一个移动(本机)和Web应用程序(SPA),它与后端微服务(在核心2.0中开发)对话,以进行身份验证/授权和其他与域相关的功能,该功能已使用Opendi的配置。这两个应用程序都获得了访问令牌。我遇到的问题是,所有微服务都应该接受无记名访问令牌和登录用户的身份验证/授权(中央身份验证服务),在身份验证微服务中生成的访问令牌(开放身份验证2.*)。那么,我在微服务中缺少哪些更改,其中REST AP

  • 我正在尝试使用Sprint安全框架在Spring Boot中为我的HTTP请求设置授权。我是Spring Security的新手,我找不到任何关于我的情况的文档。 我知道我们必须重写WebSecurity配置适配器方法-configure(AuthenticationManagerBuilder) 这是我试图建立的流程。我的前端和后端托管在不同的域中,所以我也在寻找跨来源的授权。通过发布到REST

  • 问题内容: 我一直在努力用Spring-Security 正确实现Stomp(websocket) 身份验证 和 授权 。 为了后代,我将回答我自己的问题以提供指导。 问题 Spring WebSocket文档(用于身份验证)看起来不清楚ATM(IMHO)。而且我不明白如何正确处理 身份验证 和 授权 。 我想要的是 使用登录名/密码对用户进行身份验证。 防止匿名用户通过WebSocket连接。