- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我要问的问题有点棘手,我还没有找到任何答案。也许是因为我在寻找错误的东西。但我希望你能在这方面帮助我。
我用了following tutorial实现使用 token 而不是基本用户/密码身份验证的自定义 SecurityContext。
基本上,它初始化并注入(inject)一个 ResourceFilterFactory,它本身会在每个发送到应用程序的 HTTP 请求中注入(inject)一个 ResourceFilter。
此 ResourceFilter 在请求中搜索“Authentication” header ,获取其内容,然后对用户进行身份验证。如果用户通过身份验证,则使用 SecurityContext 将其注入(inject)到请求中。
我对代码进行了转换,以使其作为 EJB 工作。
这是代码:
web.xml
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.myapp.rest.filter.ResourceFilterFactory</param-value>
</init-param>
@Named
@Stateless
@LocalBean
public class ResourceFilterFactory extends RolesAllowedResourceFilterFactory{
@EJB(name="securityContextFilter")
private SecurityContextFilter securityContextFilter;
@PostConstruct
private void init(){
System.out.println("ResourceFilterFactory initialized");
}
@Override
public List<ResourceFilter> create(AbstractMethod am) {
//System.out.println("Creating resource filters list");
List<ResourceFilter> filters = super.create(am);
if (filters == null) {
filters = new ArrayList<ResourceFilter>();
}
List<ResourceFilter> securityFilters = new ArrayList<ResourceFilter>(filters);
securityFilters.clear();
securityFilters.add(0, securityContextFilter);
return securityFilters;
}
}
@Named("securityContextFilter")
@Stateless
@LocalBean
@Provider
public class SecurityContextFilter implements ResourceFilter, ContainerRequestFilter {
protected static final String HEADER_AUTHORIZATION = "Authorization";
@EJB
private AuthorizationService authorizationService;
@Override
public ContainerRequest filter(ContainerRequest req) {
System.out.println("Auth header: " + req.getHeaderValue(HEADER_AUTHORIZATION));
String sessionToken = req.getHeaderValue(HEADER_AUTHORIZATION);
UserEntity entity = null;
try {
//entity = authorizationService.getParaUsingSessionToken(sessionToken);
// removing the part that retrieves the user from the database
ExternalUser user = new ExternalUser();
user.setEmailAddress("lol@lol.lol");
user.setFirstName("lol");
user.setLastName("LOL");
user.setRole("arole");
req.setSecurityContext(new org.company.server.rest.filter.SecurityContextImpl(user));
} catch (AuthenticationException e) {
System.out.println("authentication exception");
ExternalUser user = new ExternalUser();
req.setSecurityContext(new org.company.server.rest.filter.SecurityContextImpl(user));
}
return req;
}
@Override
public ContainerRequestFilter getRequestFilter() {
return this;
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
}
public class SecurityContextImpl implements SecurityContext {
private final ExternalUser user;
public SecurityContextImpl(ExternalUser user) {
//System.out.println("SecurityContext created : " + user.getFirstName());
this.user = user;
}
public Principal getUserPrincipal() {
return user;
}
public boolean isUserInRole(String role) {
System.out.println("Checking access rights : " + role + " / " + this.user.getRole());
return user.getRole().equalsIgnoreCase(role);
}
public boolean isSecure() {
return false;
}
public String getAuthenticationScheme() {
return SecurityContext.BASIC_AUTH;
}
}
@XmlRootElement
public class ExternalUser implements Principal {
private String id;
private String firstName;
private String lastName;
private String emailAddress;
private boolean isVerified;
private String phoneNumber;
private String professionalId;
private String role;
public ExternalUser() {}
public ExternalUser(UserEntity user) {
this.setEmailAddress(user.getEmailAddress());
this.setFirstName(user.getFirstName());
this.setLastName(user.getLastName());
this.setRole(user.getRole().toString());
this.setPhoneNumber(user.getPhoneNumber());
this.setProfessionalId(user.getProfessionnalID());
}
// Getters and setters boilerplate code...
}
@Path("/account")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Stateless
@LocalBean
public class UserRestService {
@Context
private SecurityContext security;
@GET
@Path("info")
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
public Response getInfo() {
ExternalUser user = (ExternalUser)security.getUserPrincipal();
System.out.println("Email Address Of User : " + user.getEmailAddress());
if (!security.isUserInRole("arole")){
return Response.status(403).build();
}
return Response.ok(user).build();
}
}
@RolesAllowed({"arole"})
注释,Glassfish 给了我这个错误:
INFO: JACC Policy Provider:Failed Permission Check: context (" org.company.app.server/org_company_app_server_internal ") , permission (" ("javax.security.jacc.EJBMethodPermission" "UserRestService" "getInfo,Local,org.company.server.rest.models.authentication.RestSession") ")
WARNING: EJB5184:A system exception occurred during an invocation on EJB UserRestService, method: public javax.ws.rs.core.Response org.company.server.rest.services.UserRestService.getInfo()
WARNING: javax.ejb.AccessLocalException: Client not authorized for this invocation
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1888)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy140.getInfoPara(Unknown Source)
at org.company.server.rest.services.__EJB31_Generated__UserRestService__Intf____Bean__.getInfoPara(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:895)
at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:843)
at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:804)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
WARNING: StandardWrapperValve[default]: PWC1406: Servlet.service() for servlet default threw exception
javax.ejb.AccessLocalException: Client not authorized for this invocation
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1888)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy140.getInfoPara(Unknown Source)
at org.company.server.rest.services.__EJB31_Generated__UserRestService__Intf____Bean__.getInfoPara(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
...
isUserInRole()
手动方法,但我只是避免问题而不是面对它。
最佳答案
好的,我刚刚完成了那部分(实际上除了 EmailGateway 之外的所有部分)。
首先,我要感谢 Iain Porter 的工作——它的顶级品质。对于之前错误地将他称为“波特”,我深表歉意。
Stackoverflow 代码格式存在一些问题,因此请注意某些代码会继续执行代码框。
对于您的问题,我这样做了:
AuthApplicationConfig.java
而不是 web.xml 并注册各种提供程序@ApplicationPath("rest")
public class AuthApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
// REST resources
resources.add(HealthCheckResource.class);
resources.add(PasswordResource.class);
resources.add(UserResource.class);
resources.add(VerificationResource.class);
// Filters (Auth)
resources.add(RolesAllowedDynamicFeature.class);
resources.add(SecurityContextFilter.class);
// Misc
resources.add(GenericExceptionMapper.class);
return resources;
}
}
@Provider
注释的
@Provider
@Priority(Priorities.AUTHENTICATION) // So it comes in before org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature
public class SecurityContextFilter implements ContainerRequestFilter {
@Inject
Logger logger;
protected static final String HEADER_AUTHORIZATION = "Authorization";
protected static final String HEADER_DATE = "x-java-rest-date";
protected static final String HEADER_NONCE = "nonce";
private AuthorizationService authorizationService;
ApplicationConfig config;
@Inject
public SecurityContextFilter(UserRepository userRepository,
UserService userService, ApplicationConfig config) {
delegateAuthorizationService(userRepository, userService, config);
this.config = config;
}
/**
* If there is an Authorisation header in the request extract the session
* token and retrieve the user
*
* Delegate to the AuthorizationService to validate the request
*
* If the request has a valid session token and the user is validated then a
* user object will be added to the security context
*
* Any Resource Controllers can assume the user has been validated and can
* merely authorize based on the role
*
* Resources with @PermitAll annotation do not require an Authorization
* header but will still be filtered
*
* @param request
* the ContainerRequest to filter
*
*/
@Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
System.out.println("SecurityContextFilter / filter("+printContainerRequestContext(requestContext)+")");
String authToken = requestContext.getHeaderString(HEADER_AUTHORIZATION);
String requestDateString = requestContext.getHeaderString(HEADER_DATE);
String nonce = requestContext.getHeaderString(HEADER_NONCE);
AuthorizationRequestContext context = new AuthorizationRequestContext(
requestContext.getUriInfo().getPath(),
requestContext.getMethod(), requestDateString, nonce, authToken);
ExternalUser externalUser = authorizationService.authorize(context);
requestContext
.setSecurityContext(new SecurityContextImpl(externalUser));
System.out.println(String.format(" END OF SecurityContextFilter / filter - AuthorizationRequestContext: %s, externalUser:%s", context,externalUser));
}
private String printContainerRequestContext(ContainerRequestContext requestContext) {
return String.format("[ContainerRequestContext:%s]", requestContext);
}
/**
* Specify the AuthorizationService that the application should use
*
* @param userRepository
* @param userService
* @param config
*/
private void delegateAuthorizationService(UserRepository userRepository,
UserService userService, ApplicationConfig config) {
System.out.println("SecurityContextFilter - requireSignedRequests?"+config.requireSignedRequests());
if (config.requireSignedRequests()) {
this.authorizationService = new RequestSigningAuthorizationService(
userRepository, userService, config);
} else {
this.authorizationService = new SessionTokenAuthorizationService(
userRepository);
}
}
@Inject
public void setConfig(ApplicationConfig config) {
this.config = config;
}
}
public class SecurityContextImpl implements SecurityContext {
private final ExternalUser user;
public SecurityContextImpl(ExternalUser user) {
this.user = user;
}
@Override
public Principal getUserPrincipal() {
return user;
}
@Override
public boolean isUserInRole(String role) {
if(role.equalsIgnoreCase(Role.anonymous.name())) {
return true;
}
if(user == null) {
throw new InvalidAuthorizationHeaderException();
}
System.out.println(String.format("SecurityContextImpl / isUserInRole - role:%s, user:%s", role, user));
return user.getRole().equalsIgnoreCase(role);
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getAuthenticationScheme() {
return SecurityContext.BASIC_AUTH;
}
}
@Path("/user")
// @Component
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
@RequestScoped
public class UserResource {
// A Social thing that is not needed
// private ConnectionFactoryLocator connectionFactoryLocator;
@Inject
Logger logger;
@Inject
protected UserService userService;
@Inject
protected VerificationTokenService verificationTokenService;
@Inject
protected EmailServicesGateway emailServicesGateway;
@Context
protected UriInfo uriInfo;
// @Inject
// protected ApplicationConfig config;
// @Autowired
// public UserResource(ConnectionFactoryLocator connectionFactoryLocator) {
// this.connectionFactoryLocator = connectionFactoryLocator;
// }
@PermitAll
@POST
public Response signupUser(CreateUserRequest request) {
AuthenticatedUserToken token = userService.createUser(request, Role.authenticated);
verificationTokenService.sendEmailRegistrationToken(token.getUserId());
URI location = uriInfo.getAbsolutePathBuilder().path(token.getUserId()).build();
return Response.created(location).entity(token).build();
}
@RolesAllowed("admin")
@Path("{userId}")
@DELETE
public Response deleteUser(@Context SecurityContext sc, @PathParam("userId") String userId) {
ExternalUser userMakingRequest = (ExternalUser) sc.getUserPrincipal();
userService.deleteUser(userMakingRequest, userId);
return Response.ok().build();
}
...
关于jakarta-ee - Glassfish @RolesAllowed 与自定义 SecurityContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17486746/
我正在开发一个项目,该项目具有用 @RolesAllowed 注释的服务。我知道这个注释定义了可以访问该方法的角色。但我不确定这些角色是在哪里定义的以及如何为不同的角色添加用户。我使用 weblogi
我必须将方法的访问限制为仅具有特定角色的用户。IdentityManager 已正确构建。 我有这个 Controller 类。 @Named @RequestScoped @LoggedIn pub
我目前正在Tomcat 7中使用Jersey 2.5.1创建后端服务器。为了安全起见,我使用了@RolesAllowed,@PermitAll等批注,并且创建了自定义的ContainerRequest
在 Spring Boot 应用程序中,仅使用注释,我想实现安全性 我已将 @EnableGlobalMethodSecurity(jsr360Enabled=true) 添加到配置类。该类还有一个
我的数据库中有两个表格。用户和 user_role。 CREATE TABLE `user` ( `username` varchar(50) NOT NULL, `password` var
TLDR我开发的Java Web应用程序需要在REST服务上实现用户区分。我知道有一些注释(@RolesAllowed、@PermitAll、@DenyAll)可以描述哪个角色可以使用该服务。我的问题
我正在使用 keycloak,我已经创建了一个 dropwizard 服务,我想开始在其中执行角色。 我试过使用@RolesAllowd("user") 注释,但它总是返回 403。 我也试过@Per
我有一个名为和 SessionScoped 的 JSF Controller ,如下所示 import javax.inject.Named; import javax.enterprise.cont
我在设置安全 REST 服务时遇到一些问题。我想创建一个简单的登录/注销服务并使用它。 我正在关注本教程。我跳过了登录表单的部分,并将用户名和密码硬编码到服务中。 (登录()) http://www.
我正在使用 JAX-RS 和 Jersey 实现。我正在尝试使用 Tomcat 6 使用 BASIC 身份验证来验证我的服务。 这是代码: @Path("/authenticate") @RolesA
我正在使用 Spring @RolesAllowed 来保护我的 API(方法),但我想更改未经授权的用户调用方法时发生的情况。当前的行为是 Spring 抛出 HTTP 403 错误。这很棒,但我只
我正在使用 App Engine 和 Jersey 构建应用程序。我想使用允许在请求中创建过滤器的注释 @RolesAllowed(Role_user)。 问题是我们需要配置类SecurityCont
我要问的问题有点棘手,我还没有找到任何答案。也许是因为我在寻找错误的东西。但我希望你能在这方面帮助我。 我用了following tutorial实现使用 token 而不是基本用户/密码身份验证的自
我希望向客户端提供休息 API 调用(通过普通 Jersey ,而不是 spring),以根据他们在 header 中发送的 JWT 返回特定用户允许的所有端点的列表。我在 stackoverflow
我有一个基本的 SpringBoot 应用程序。使用 Spring Initializer、嵌入式 Tomcat、Thymeleaf 模板引擎,并将其打包为可执行的 JAR 文件。 @Configur
我在我的应用程序中使用角色授权,如下所示, **@RolesAllowed("Admin")** public class ExampleResource { // @GET @Produce
我想将 Jersey 的 DeclarativeLinking 特性与其 RolesAllowed 特性结合起来。 我能够成功地将链接注入(inject)到响应中,但该注入(inject)并未关注该端
我有一个简单的 jersey 2.4 资源: @RolesAllowed("admin") public List list(){} 我还有一个设置自定义安全上下文的 ContainerRequest
我正在尝试根据我通过 Jersey/JAX-RS 公开的资源的角色设置身份验证。此资源存在于 Glassfish 实例中,其中基于角色的身份验证(具体而言,通过 @RolesAllowed)当前正在按
我们正在通过 postman 休息客户端测试在 Jersey 开发的 REST 网络服务。它是一个 POST 方法,用 @RolesAllowed 注释。该方法完整注解如下: @POST @Path(
我是一名优秀的程序员,十分优秀!