- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 Azure 实现 SSO 到使用 Struts 2 构建的应用程序,我已经实现了过滤器以使我能够从 microsoft 页面登录。
但是,当一切正确时,重定向问题对我来说不太清楚,因为我不太擅长 Struts,因为当您最初登录应用程序时,它会重定向到这样的 URL localhost:8080/Portal/login/loginAction_validateUser.action
.
这是应用程序的原始登录类
public class ActionLogin extends ActionSupport implements ServletRequestAware {
private static Logger logger = LogManager.getLogger(ActionLogin.class);
private HttpServletRequest request;
private UtilHttp uhttp = new UtilHttp();
private UtilFiles ufiles = new UtilFiles();
private User user;
private Person person;
private int invalidateSession;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public String validateUser() {
try {
HttpSession session = request.getSession();
uhttp.cleanSession(request);
LoginBusiness business = new LoginBusiness();
String page = "menu";
boolean loadMenu = true;
if (invalidateSession == 1) {
new LoginBusiness().createDifferentSession(session, user.getLogin());
invalidateSession = 0;
}
user = business.validateUser(user.getLogin(), user.getPassword(), user.getIdProfile());
if (business.isUserLocked(user.getIdUser())) {
addActionError(PortalAdministracionErrorCode.E0400.getMessage());
return "blockedAccount";
}
if (user.isValidAuth()) {
logger.info("user.isValidAuth()");
if (user.isChangePassword()) {
loadMenu = false;
page = "change";
}
if (business.isPasswordExpired(user.getIdUser())) {
addActionError(getText(PortalAdministracionErrorCode.E0401.getMessage()));
loadMenu = false;
return "passwordexpired";
}
session = request.getSession(true);
session.setAttribute(Constants.SESSION_USER, user);
} else {
addActionError(getText("label.error.login.password"));
user.setAuthType("1");
page = "login";
}
return page;
} catch (Exception e) {
addActionError(e.getMessage());
return "login";
}
}
public String logOut() {
HttpSession session = request.getSession(false);
if (session != null) {
try {
logger.info("Realiza un logOut el usuario ");
uhttp.cleanSession(request);
return "logout";
//session.invalidate();
} catch (Exception ex) {
logger.error(ex);
return "logout";
}
}
return "logout";
}
public String invalidateSession() {
invalidateSession = 0;
return "login";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public int getInvalidateSession() {
return invalidateSession;
}
public void setInvalidateSession(int invalidateSession) {
this.invalidateSession = invalidateSession;
}
}
这是使用 struts 配置的 XML,当登录正常时,它会重定向到名为 entrada.jsp 的 JSP,但在 url 中,如果它没有将登录的操作放在执行此操作时,它不会更改制作完成后,知道如何适应它吗?
我的登录.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="login" namespace="/login" extends="struts-default,json-default">
<interceptors>
<interceptor-stack name="defaultSecurityStack">
<interceptor-ref name="tokenSession">
<param name="excludeMethods">*</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defaultSecurityStack" />
<global-results>
<result name="error">/jsp/common/errorDetail.jsp</result>
<result name="invalid.token">/jsp/Login.jsp</result>
</global-results>
<action name="loginAction_*" method="{1}" class="action.ActionLogin">
<result name="login">/jsp/Login.jsp</result>
<result name="menu">/jsp/menu/Entrada.jsp</result>
<result name="platformAdmon">/jsp/profile/AddPlatformAdmon.jsp</result>
<result name="change">/jsp/menu/ChangePassword.jsp</result>
<result name="passwordexpired">/jsp/login/account/password-expired.jsp</result>
<result name="success">/jsp/menu/ResultOperation.jsp</result>
<result name="blockedAccount">/jsp/login/account/blocked.jsp</result>
<result name="logout">/jsp/logout.jsp</result>
<interceptor-ref name="defaultSecurityStack">
<param name="tokenSession.excludeMethods">validatePlatformAdmin,logOut,editPassword</param>
</interceptor-ref>
<allowed-methods>toPageLogin, addPlatformAdmon, authType, changePassword, editPassword, logOut, showMenu, validatePlatformAdmin, validateUser</allowed-methods>
</action>
<action name="account_*" method="{1}" class="com.seguridata.rne.administracion.portal.action.LoginAccountAction">
<result name="login">/jsp/Login.jsp</result>
<result name="blocked">/jsp/login/account/blocked.jsp</result>
<result name="resultblocked">/jsp/login/account/blocked-response.jsp</result>
<result name="unlock">/jsp/login/account/unlock.jsp</result>
<result name="resultunlock">/jsp/login/account/unlock-response.jsp</result>
<result name="passwordexpired">/jsp/login/account/password-expired.jsp</result>
<result name="passwordexpired_success">/jsp/login/account/password-expired-success.jsp</result>
<interceptor-ref name="defaultSecurityStack">
<param name="tokenSession.excludeMethods">*</param>
</interceptor-ref>
<allowed-methods>unlock, unlockRequest, updatePasswordExpired, validateUnlockRequest</allowed-methods>
</action>
</package>
</struts>
这是我的 SSO 重定向过滤器代码,我在这里并没有真正看到问题,但在 Azure 的配置中
public class BasicFilter implements Filter {
public static final String STATES = "states";
public static final String STATE = "state";
public static final Integer STATE_TTL = 3600;
public static final String FAILED_TO_VALIDATE_MESSAGE = "Failed to validate data received from Authorization service - ";
private String clientId = "";
private String clientSecret = "";
private String tenant = "";
private String authority;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
try {
String currentUri = httpRequest.getRequestURL().toString();
String queryStr = httpRequest.getQueryString();
String fullUrl = currentUri + (queryStr != null ? "?" + queryStr : "");
// check if user has a AuthData in the session
if (!AuthHelper.isAuthenticated(httpRequest)) {
if (AuthHelper.containsAuthenticationData(httpRequest)) {
processAuthenticationData(httpRequest, currentUri, fullUrl);
} else {
// not authenticated
sendAuthRedirect(httpRequest, httpResponse);
return;
}
}
if (isAuthDataExpired(httpRequest)) {
updateAuthDataUsingRefreshToken(httpRequest);
}
} catch (AuthenticationException authException) {
// something went wrong (like expiration or revocation of token)
// we should invalidate AuthData stored in session and redirect to Authorization server
removePrincipalFromSession(httpRequest);
sendAuthRedirect(httpRequest, httpResponse);
return;
} catch (Throwable exc) {
httpResponse.setStatus(500);
request.setAttribute("error", exc.getMessage());
request.getRequestDispatcher("/error.jsp").forward(request, response);
}
}
chain.doFilter(request, response);
}
private boolean isAuthDataExpired(HttpServletRequest httpRequest) {
AuthenticationResult authData = AuthHelper.getAuthSessionObject(httpRequest);
return authData.getExpiresOnDate().before(new Date()) ? true : false;
}
private void updateAuthDataUsingRefreshToken(HttpServletRequest httpRequest) throws Throwable {
AuthenticationResult authData =
getAccessTokenFromRefreshToken(AuthHelper.getAuthSessionObject(httpRequest).getRefreshToken());
setSessionPrincipal(httpRequest, authData);
}
private void processAuthenticationData(HttpServletRequest httpRequest, String currentUri, String fullUrl)
throws Throwable {
HttpSession session = httpRequest.getSession(false);
HashMap<String, String> params = new HashMap<>();
for (String key : httpRequest.getParameterMap().keySet()) {
params.put(key, httpRequest.getParameterMap().get(key)[0]);
}
// validate that state in response equals to state in request
StateData stateData = validateState(httpRequest.getSession(), params.get(STATE));
AuthenticationResponse authResponse = AuthenticationResponseParser.parse(new URI(fullUrl), params);
if (AuthHelper.isAuthenticationSuccessful(authResponse)) {
AuthenticationSuccessResponse oidcResponse = (AuthenticationSuccessResponse) authResponse;
// validate that OIDC Auth Response matches Code Flow (contains only requested artifacts)
validateAuthRespMatchesCodeFlow(oidcResponse);
AuthenticationResult authData =
getAccessToken(oidcResponse.getAuthorizationCode(), currentUri);
// validate nonce to prevent reply attacks (code maybe substituted to one with broader access)
validateNonce(stateData, getClaimValueFromIdToken(authData.getIdToken(), "nonce"));
setSessionPrincipal(httpRequest, authData);
} else {
AuthenticationErrorResponse oidcResponse = (AuthenticationErrorResponse) authResponse;
throw new Exception(String.format("Request for auth code failed: %s - %s",
oidcResponse.getErrorObject().getCode(),
oidcResponse.getErrorObject().getDescription()));
}
}
private void validateNonce(StateData stateData, String nonce) throws Exception {
if (StringUtils.isEmpty(nonce) || !nonce.equals(stateData.getNonce())) {
throw new Exception(FAILED_TO_VALIDATE_MESSAGE + "could not validate nonce");
}
}
private String getClaimValueFromIdToken(String idToken, String claimKey) throws ParseException {
return (String) JWTParser.parse(idToken).getJWTClaimsSet().getClaim(claimKey);
}
private void sendAuthRedirect(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
httpResponse.setStatus(302);
// use state parameter to validate response from Authorization server
String state = UUID.randomUUID().toString();
// use nonce parameter to validate idToken
String nonce = UUID.randomUUID().toString();
storeStateInSession(httpRequest.getSession(), state, nonce);
String currentUri = httpRequest.getRequestURL().toString();
httpResponse.sendRedirect(getRedirectUrl(currentUri, state, nonce));
}
/**
* make sure that state is stored in the session,
* delete it from session - should be used only once
*
* @param session
* @param state
* @throws Exception
*/
private StateData validateState(HttpSession session, String state) throws Exception {
if (StringUtils.isNotEmpty(state)) {
StateData stateDataInSession = removeStateFromSession(session, state);
if (stateDataInSession != null) {
return stateDataInSession;
}
}
throw new Exception(FAILED_TO_VALIDATE_MESSAGE + "could not validate state");
}
private void validateAuthRespMatchesCodeFlow(AuthenticationSuccessResponse oidcResponse) throws Exception {
if (oidcResponse.getIDToken() != null || oidcResponse.getAccessToken() != null ||
oidcResponse.getAuthorizationCode() == null) {
throw new Exception(FAILED_TO_VALIDATE_MESSAGE + "unexpected set of artifacts received");
}
}
@SuppressWarnings("unchecked")
private StateData removeStateFromSession(HttpSession session, String state) {
Map<String, StateData> states = (Map<String, StateData>) session.getAttribute(STATES);
if (states != null) {
eliminateExpiredStates(states);
StateData stateData = states.get(state);
if (stateData != null) {
states.remove(state);
return stateData;
}
}
return null;
}
@SuppressWarnings("unchecked")
private void storeStateInSession(HttpSession session, String state, String nonce) {
if (session.getAttribute(STATES) == null) {
session.setAttribute(STATES, new HashMap<String, StateData>());
}
((Map<String, StateData>) session.getAttribute(STATES)).put(state, new StateData(nonce, new Date()));
}
private void eliminateExpiredStates(Map<String, StateData> map) {
Iterator<Map.Entry<String, StateData>> it = map.entrySet().iterator();
Date currTime = new Date();
while (it.hasNext()) {
Map.Entry<String, StateData> entry = it.next();
long diffInSeconds = TimeUnit.MILLISECONDS.
toSeconds(currTime.getTime() - entry.getValue().getExpirationDate().getTime());
if (diffInSeconds > STATE_TTL) {
it.remove();
}
}
}
private AuthenticationResult getAccessTokenFromRefreshToken(
String refreshToken) throws Throwable {
AuthenticationContext context;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(authority + tenant + "/", true,
service);
Future<AuthenticationResult> future = context
.acquireTokenByRefreshToken(refreshToken, new ClientCredential(clientId, clientSecret), null, null);
result = future.get();
} catch (ExecutionException e) {
throw e.getCause();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
return result;
}
private AuthenticationResult getAccessToken(
AuthorizationCode authorizationCode, String currentUri)
throws Throwable {
String authCode = authorizationCode.getValue();
ClientCredential credential = new ClientCredential(clientId,
clientSecret);
AuthenticationContext context;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(authority + tenant + "/", true,
service);
Future<AuthenticationResult> future = context
.acquireTokenByAuthorizationCode(authCode, new URI(
currentUri), credential, null);
result = future.get();
} catch (ExecutionException e) {
throw e.getCause();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
return result;
}
private void setSessionPrincipal(HttpServletRequest httpRequest,
AuthenticationResult result) {
httpRequest.getSession().setAttribute(AuthHelper.PRINCIPAL_SESSION_NAME, result);
}
private void removePrincipalFromSession(HttpServletRequest httpRequest) {
httpRequest.getSession().removeAttribute(AuthHelper.PRINCIPAL_SESSION_NAME);
}
private String getRedirectUrl(String currentUri, String state, String nonce)
throws UnsupportedEncodingException {
String redirectUrl = authority
+ this.tenant
+ "/oauth2/authorize?response_type=code&scope=directory.read.all&response_mode=form_post&redirect_uri="
+ URLEncoder.encode(currentUri, "UTF-8") + "&client_id="
+ clientId + "&resource=https%3a%2f%2fgraph.microsoft.com"
+ "&state=" + state
+ "&nonce=" + nonce;
return redirectUrl;
}
public void init(FilterConfig config) throws ServletException {
clientId = config.getInitParameter("client_id");
authority = config.getServletContext().getInitParameter("authority");
tenant = config.getServletContext().getInitParameter("tenant");
clientSecret = config.getInitParameter("secret_key");
}
private class StateData {
private String nonce;
private Date expirationDate;
public StateData(String nonce, Date expirationDate) {
this.nonce = nonce;
this.expirationDate = expirationDate;
}
public String getNonce() {
return nonce;
}
public Date getExpirationDate() {
return expirationDate;
}
}
}
我的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>struts-prepare</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareFilter</filter-class>
</filter>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter>
<filter-name>struts-execute</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsExecuteFilter</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-prepare</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-execute</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<jsp-config>
<taglib>
<taglib-uri>/struts-tags</taglib-uri>
<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-page</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-decorator</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
</taglib>
</jsp-config>
<welcome-file-list>
<welcome-file>/jsp/Login.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>authority</param-name>
<param-value>https://login.windows.net/</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<context-param>
<param-name>tenant</param-name>
<param-value>mytenat</param-value>
</context-param>
<filter-mapping>
<filter-name>BasicFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>BasicFilter</filter-name>
<filter-class>mx.prototype.adaj4jAzure.BasicFilter</filter-class>
<init-param>
<param-name>client_id</param-name>
<param-value>myclientid</param-value>
</init-param>
<init-param>
<param-name>secret_key</param-name>
<param-value>secretkeyy</param-value>
</init-param>
</filter>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
我的struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<constant name="struts.devMode" value="false" />
<constant name="struts.configuration.xml.reload" value="false" />
<constant name="struts.i18n.reload" value="false" />
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<constant name="struts.multipart.maxSize" value="5242880"/>
-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<constant name="struts.multipart.maxSize" value="524288000" />
<constant name="struts.devMode" value="false" />
<constant name="struts.i18n.reload" value="false"/>
<constant name="struts.configuration.xml.reload" value="false"/>
<constant name="struts.freemarker.templatesCache" value="true"/>
<constant name="struts.freemarker.templatesCache.updateDelay" value="120"/>
<constant name="struts.freemarker.mru.max.strong.size" value="120"/>
<constant name="struts.action.excludePattern" value="/struts/webconsole.html" />
<constant name="struts.action.excludePattern" value="/struts/webconsole.css"/>
<constant name="struts.action.excludePattern" value="/struts/webconsole.js"/>
<include file="strutsDomain.xml"/>
<include file="strutsLogin.xml"/>
<include file="strutsPasswordParameters.xml"/>
<include file="strutsPersonalize.xml"/>
<include file="strutsProfile.xml"/>
<include file="strutsTemplate.xml"/>
<include file="strutsRoute.xml"/>
<include file="strutsPlantillas.xml"/>
<package name="serveAll" namespace="" extends="struts-default">
<action name="*">
<result>/jsp/common/error.jsp</result>
</action>
</package>
</struts>
最佳答案
我认为你的过滤器看起来确实不错。
错误可能出在您的 LoginAction
中,您需要使其适应新的身份验证流程并删除旧的内容。请考虑以下简化:
public class ActionLogin extends ActionSupport implements ServletRequestAware {
private static Logger logger = LogManager.getLogger(ActionLogin.class);
private HttpServletRequest request;
private UtilHttp uhttp = new UtilHttp();
private UtilFiles ufiles = new UtilFiles();
private User user;
private Person person;
private int invalidateSession;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public String validateUser() {
try {
HttpSession session = request.getSession();
// First, you need to obtain a reference to the AuthenticationResult
// your filter defined the session with the setSessionPrincipal method
AuthenticationResult authenticationResult) =
(AuthenticationResult)session.getAttribute(AuthHelper.PRINCIPAL_SESSION_NAME);
// Handle authenticationResult == null case, probably redirecting
// to an error or 403 page
if (authenticationResult == null) {
return "error";
}
// Obtain user information from the AuthenticationResult
// Debug the object and see what information is provided
// in the associated UserInfo object, or use the idToken,
// something that allows you to uniquely identify your user
String userId = "...";
// Now, obtain user information from the database
// probably you will need to define a new method in LoginBusiness
LoginBusiness business = new LoginBusiness();
user = business.getUser(userId);
// Perhaps this condition is right, I don't know
if (business.isUserLocked(user.getIdUser())) {
addActionError(PortalAdministracionErrorCode.E0400.getMessage());
return "blockedAccount";
}
// set the user attribute in order to allow the rest of your code
// to work properly
session.setAttribute(Constants.SESSION_USER, user);
return "menu";
} catch (Exception e) {
addActionError(e.getMessage());
return "error";
}
}
// Probaly logout, etcetera should be changed as well
// I don't know whether the rest of the code should or not be
// maintained: it will greatly depend on the rest of your application
public String logOut() {
HttpSession session = request.getSession(false);
if (session != null) {
try {
logger.info("Realiza un logOut el usuario ");
uhttp.cleanSession(request);
return "logout";
//session.invalidate();
} catch (Exception ex) {
logger.error(ex);
return "logout";
}
}
return "logout";
}
public String invalidateSession() {
invalidateSession = 0;
return "login";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public int getInvalidateSession() {
return invalidateSession;
}
public void setInvalidateSession(int invalidateSession) {
this.invalidateSession = invalidateSession;
}
}
login.xml
文件也可以简化:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="login" namespace="/login" extends="struts-default,json-default">
<interceptors>
<interceptor-stack name="defaultSecurityStack">
<interceptor-ref name="tokenSession">
<param name="excludeMethods">*</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defaultSecurityStack" />
<global-results>
<result name="error">/jsp/common/errorDetail.jsp</result>
<result name="invalid.token">/jsp/Login.jsp</result>
</global-results>
<action name="loginAction_*" method="{1}" class="action.ActionLogin">
<result name="menu">/jsp/menu/Entrada.jsp</result>
<result name="blockedAccount">/jsp/login/account/blocked.jsp</result>
<result name="logout">/jsp/logout.jsp</result>
<interceptor-ref name="defaultSecurityStack">
<param name="tokenSession.excludeMethods">validatePlatformAdmin,logOut,editPassword</param>
</interceptor-ref>
<allowed-methods>toPageLogin, addPlatformAdmon, authType, changePassword, editPassword, logOut, showMenu, validatePlatformAdmin, validateUser</allowed-methods>
</action>
<action name="account_*" method="{1}" class="com.seguridata.rne.administracion.portal.action.LoginAccountAction">
<result name="login">/jsp/Login.jsp</result>
<result name="blocked">/jsp/login/account/blocked.jsp</result>
<result name="resultblocked">/jsp/login/account/blocked-response.jsp</result>
<result name="unlock">/jsp/login/account/unlock.jsp</result>
<result name="resultunlock">/jsp/login/account/unlock-response.jsp</result>
<result name="passwordexpired">/jsp/login/account/password-expired.jsp</result>
<result name="passwordexpired_success">/jsp/login/account/password-expired-success.jsp</result>
<interceptor-ref name="defaultSecurityStack">
<param name="tokenSession.excludeMethods">*</param>
</interceptor-ref>
<allowed-methods>unlock, unlockRequest, updatePasswordExpired, validateUnlockRequest</allowed-methods>
</action>
</package>
</struts>
我只编辑了对我来说显而易见的路径,也许这个配置可以大大简化,尤其是与 defaultSecurityStack
相关的路径。
最后,考虑更改 web.xml
文件中过滤器的顺序,对于按定义顺序调用它们的相同路径,请确保 BasicFilter
是第一个:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>authority</param-name>
<param-value>https://login.windows.net/</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<context-param>
<param-name>tenant</param-name>
<param-value>mytenat</param-value>
</context-param>
<filter>
<filter-name>BasicFilter</filter-name>
<filter-class>mx.prototype.adaj4jAzure.BasicFilter</filter-class>
<init-param>
<param-name>client_id</param-name>
<param-value>myclientid</param-value>
</init-param>
<init-param>
<param-name>secret_key</param-name>
<param-value>secretkeyy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>BasicFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts-prepare</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareFilter</filter-class>
</filter>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter>
<filter-name>struts-execute</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsExecuteFilter</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-prepare</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-execute</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<jsp-config>
<taglib>
<taglib-uri>/struts-tags</taglib-uri>
<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-page</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-decorator</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
</taglib>
</jsp-config>
<welcome-file-list>
<welcome-file>/jsp/Login.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
关于java - 如何使用 Azure SSO 在 Struts 2 中重定向应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71246280/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!