Hybris webservices 始终将匿名用户设置为当前用户
Hybris webservices always sets anonymous user as current user
我已经在我的店面中添加了一个基于 commercewebservices 的新扩展,并且我已经通过 swagger 直接测试了几个示例服务,并且那些不需要任何类型的授权的工作完美。但是,当我设置 userId 和 siteParam 时,用 @ApiBaseSiteIdAndUserIdParam
注释的 Web 服务拦截此请愿书的控制器不会在会话中设置我传递的用户,它始终是 return 匿名用户。我试过创建特殊的 OAuth 凭据,但它总是不起作用 returns 匿名用户。
@Secured({ "ROLE_CUSTOMERGROUP", "ROLE_TRUSTED_CLIENT", "ROLE_CUSTOMERMANAGERGROUP" })
@GetMapping(value = "/test")
@ResponseBody
@ApiBaseSiteIdAndUserIdParam
public TestListWsDTO getTest(
@RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) {
final CustomerData customerData = customerFacade.getCurrentCustomer();
if (userFacade.isAnonymousUser()) {
throw new AccessDeniedException("Anonymous user is not allowed");
}
test@test.com是注册用户
为什么我通过 swagger 指出的客户没有被 customerFacade.getCurrentCustomer() 捕获并且总是 return 匿名?
如果您使用 OCC 网络服务,这些服务是无状态的。所以你不能从会话变量中获取任何值。一般storefront使用的facades和storefronts使用session。
在 OCC 上下文中,当前用户由 OAuth 令牌确定。如果您只有客户端凭据,那么您就是匿名的。但是,在特定于用户的登录之后,您有一个不同的令牌,该令牌与使用 OAuth 进行身份验证的用户相关联。 commercewebservices 堆栈中应该有一个过滤器,用于检查令牌并映射到临时会话中的当前用户。据我所知,只有该用户会显示为当前客户,而不是 URL 中传递的客户......您可能想检查当前客户是否是同一用户(或者应该有权查看有关该用户的详细信息)
根据@Neil,如果 OCC V2 上下文用户是由 OAuth 令牌确定的,这是正确的。
对于 OCC,还有已配置的过滤器,用于配置或将用户用户置于会话中(如果找到),否则它将设置为匿名。
请查看 UserMatchingFilter。
/*
* [y] hybris Platform
*
* Copyright (c) 2017 SAP SE or an SAP affiliate company. All rights reserved.
*
* This software is the confidential and proprietary information of SAP
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SAP.
*/
package de.hybris.platform.ycommercewebservices.v2.filter;
import de.hybris.platform.core.model.user.UserModel;
import de.hybris.platform.servicelayer.exceptions.UnknownIdentifierException;
import de.hybris.platform.servicelayer.session.SessionService;
import de.hybris.platform.servicelayer.user.UserService;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Filter that puts user from the requested url into the session.
*/
public class UserMatchingFilter extends AbstractUrlMatchingFilter
{
public static final String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
public static final String ROLE_CUSTOMERGROUP = "ROLE_CUSTOMERGROUP";
public static final String ROLE_CUSTOMERMANAGERGROUP = "ROLE_CUSTOMERMANAGERGROUP";
public static final String ROLE_TRUSTED_CLIENT = "ROLE_TRUSTED_CLIENT";
private static final String CURRENT_USER = "current";
private static final String ANONYMOUS_USER = "anonymous";
private static final String ACTING_USER_UID = "ACTING_USER_UID";
private static final Logger LOG = Logger.getLogger(UserMatchingFilter.class);
private String regexp;
private UserService userService;
private SessionService sessionService;
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException
{
final Authentication auth = getAuth();
if (hasRole(ROLE_CUSTOMERGROUP, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
getSessionService().setAttribute(ACTING_USER_UID, auth.getPrincipal());
}
final String userID = getValue(request, regexp);
if (userID == null)
{
if (hasRole(ROLE_CUSTOMERGROUP, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
setCurrentUser((String) auth.getPrincipal());
}
else
{
// fallback to anonymous
setCurrentUser(userService.getAnonymousUser());
}
}
else if (userID.equals(ANONYMOUS_USER))
{
setCurrentUser(userService.getAnonymousUser());
}
else if (hasRole(ROLE_TRUSTED_CLIENT, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
setCurrentUser(userID);
}
else if (hasRole(ROLE_CUSTOMERGROUP, auth))
{
if (userID.equals(CURRENT_USER) || userID.equals(auth.getPrincipal()))
{
setCurrentUser((String) auth.getPrincipal());
}
else
{
throw new AccessDeniedException("Access is denied");
}
}
else
{
// could not match any authorized role
throw new AccessDeniedException("Access is denied");
}
filterChain.doFilter(request, response);
}
protected Authentication getAuth()
{
return SecurityContextHolder.getContext().getAuthentication();
}
protected String getRegexp()
{
return regexp;
}
@Required
public void setRegexp(final String regexp)
{
this.regexp = regexp;
}
protected UserService getUserService()
{
return userService;
}
@Required
public void setUserService(final UserService userService)
{
this.userService = userService;
}
protected SessionService getSessionService()
{
return sessionService;
}
@Required
public void setSessionService(final SessionService sessionService)
{
this.sessionService = sessionService;
}
protected boolean hasRole(final String role, final Authentication auth)
{
if (auth != null)
{
for (final GrantedAuthority ga : auth.getAuthorities())
{
if (ga.getAuthority().equals(role))
{
return true;
}
}
}
return false;
}
protected void setCurrentUser(final String uid)
{
try
{
final UserModel userModel = userService.getUserForUID(uid);
userService.setCurrentUser(userModel);
}
catch (final UnknownIdentifierException ex)
{
LOG.debug(ex.getMessage());
throw ex;
}
}
protected void setCurrentUser(final UserModel user)
{
userService.setCurrentUser(user);
}
}
我已经在我的店面中添加了一个基于 commercewebservices 的新扩展,并且我已经通过 swagger 直接测试了几个示例服务,并且那些不需要任何类型的授权的工作完美。但是,当我设置 userId 和 siteParam 时,用 @ApiBaseSiteIdAndUserIdParam
注释的 Web 服务拦截此请愿书的控制器不会在会话中设置我传递的用户,它始终是 return 匿名用户。我试过创建特殊的 OAuth 凭据,但它总是不起作用 returns 匿名用户。
@Secured({ "ROLE_CUSTOMERGROUP", "ROLE_TRUSTED_CLIENT", "ROLE_CUSTOMERMANAGERGROUP" })
@GetMapping(value = "/test")
@ResponseBody
@ApiBaseSiteIdAndUserIdParam
public TestListWsDTO getTest(
@RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) {
final CustomerData customerData = customerFacade.getCurrentCustomer();
if (userFacade.isAnonymousUser()) {
throw new AccessDeniedException("Anonymous user is not allowed");
}
test@test.com是注册用户
为什么我通过 swagger 指出的客户没有被 customerFacade.getCurrentCustomer() 捕获并且总是 return 匿名?
如果您使用 OCC 网络服务,这些服务是无状态的。所以你不能从会话变量中获取任何值。一般storefront使用的facades和storefronts使用session。
在 OCC 上下文中,当前用户由 OAuth 令牌确定。如果您只有客户端凭据,那么您就是匿名的。但是,在特定于用户的登录之后,您有一个不同的令牌,该令牌与使用 OAuth 进行身份验证的用户相关联。 commercewebservices 堆栈中应该有一个过滤器,用于检查令牌并映射到临时会话中的当前用户。据我所知,只有该用户会显示为当前客户,而不是 URL 中传递的客户......您可能想检查当前客户是否是同一用户(或者应该有权查看有关该用户的详细信息)
根据@Neil,如果 OCC V2 上下文用户是由 OAuth 令牌确定的,这是正确的。
对于 OCC,还有已配置的过滤器,用于配置或将用户用户置于会话中(如果找到),否则它将设置为匿名。
请查看 UserMatchingFilter。
/*
* [y] hybris Platform
*
* Copyright (c) 2017 SAP SE or an SAP affiliate company. All rights reserved.
*
* This software is the confidential and proprietary information of SAP
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SAP.
*/
package de.hybris.platform.ycommercewebservices.v2.filter;
import de.hybris.platform.core.model.user.UserModel;
import de.hybris.platform.servicelayer.exceptions.UnknownIdentifierException;
import de.hybris.platform.servicelayer.session.SessionService;
import de.hybris.platform.servicelayer.user.UserService;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Filter that puts user from the requested url into the session.
*/
public class UserMatchingFilter extends AbstractUrlMatchingFilter
{
public static final String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
public static final String ROLE_CUSTOMERGROUP = "ROLE_CUSTOMERGROUP";
public static final String ROLE_CUSTOMERMANAGERGROUP = "ROLE_CUSTOMERMANAGERGROUP";
public static final String ROLE_TRUSTED_CLIENT = "ROLE_TRUSTED_CLIENT";
private static final String CURRENT_USER = "current";
private static final String ANONYMOUS_USER = "anonymous";
private static final String ACTING_USER_UID = "ACTING_USER_UID";
private static final Logger LOG = Logger.getLogger(UserMatchingFilter.class);
private String regexp;
private UserService userService;
private SessionService sessionService;
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException
{
final Authentication auth = getAuth();
if (hasRole(ROLE_CUSTOMERGROUP, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
getSessionService().setAttribute(ACTING_USER_UID, auth.getPrincipal());
}
final String userID = getValue(request, regexp);
if (userID == null)
{
if (hasRole(ROLE_CUSTOMERGROUP, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
setCurrentUser((String) auth.getPrincipal());
}
else
{
// fallback to anonymous
setCurrentUser(userService.getAnonymousUser());
}
}
else if (userID.equals(ANONYMOUS_USER))
{
setCurrentUser(userService.getAnonymousUser());
}
else if (hasRole(ROLE_TRUSTED_CLIENT, auth) || hasRole(ROLE_CUSTOMERMANAGERGROUP, auth))
{
setCurrentUser(userID);
}
else if (hasRole(ROLE_CUSTOMERGROUP, auth))
{
if (userID.equals(CURRENT_USER) || userID.equals(auth.getPrincipal()))
{
setCurrentUser((String) auth.getPrincipal());
}
else
{
throw new AccessDeniedException("Access is denied");
}
}
else
{
// could not match any authorized role
throw new AccessDeniedException("Access is denied");
}
filterChain.doFilter(request, response);
}
protected Authentication getAuth()
{
return SecurityContextHolder.getContext().getAuthentication();
}
protected String getRegexp()
{
return regexp;
}
@Required
public void setRegexp(final String regexp)
{
this.regexp = regexp;
}
protected UserService getUserService()
{
return userService;
}
@Required
public void setUserService(final UserService userService)
{
this.userService = userService;
}
protected SessionService getSessionService()
{
return sessionService;
}
@Required
public void setSessionService(final SessionService sessionService)
{
this.sessionService = sessionService;
}
protected boolean hasRole(final String role, final Authentication auth)
{
if (auth != null)
{
for (final GrantedAuthority ga : auth.getAuthorities())
{
if (ga.getAuthority().equals(role))
{
return true;
}
}
}
return false;
}
protected void setCurrentUser(final String uid)
{
try
{
final UserModel userModel = userService.getUserForUID(uid);
userService.setCurrentUser(userModel);
}
catch (final UnknownIdentifierException ex)
{
LOG.debug(ex.getMessage());
throw ex;
}
}
protected void setCurrentUser(final UserModel user)
{
userService.setCurrentUser(user);
}
}