优化代码

pull/42/head
smallbun 2023-09-05 21:38:05 +08:00
parent 59365426ea
commit c50753b3bd
9 changed files with 144 additions and 90 deletions

View File

@ -196,12 +196,12 @@ public final class FormAuthenticationEndpointFilter extends OncePerRequestFilter
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex); this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex);
} catch (Exception ex) { } catch (Exception ex) {
FormError error = new FormError(SERVER_ERROR,ex.getMessage(),FORM_ERROR_URI); FormError error = new FormError(SERVER_ERROR, ex.getMessage(), FORM_ERROR_URI);
if (this.logger.isTraceEnabled()) { if (this.logger.isTraceEnabled()) {
this.logger.trace(error, ex); this.logger.trace(error, ex);
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new FormAuthenticationException(error)); new FormAuthenticationException(error));
} }
} }

View File

@ -1,3 +1,20 @@
/*
* eiam-protocol-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.protocol.jwt.authentication; package cn.topiam.employee.protocol.jwt.authentication;
import java.io.IOException; import java.io.IOException;

View File

@ -1,3 +1,20 @@
/*
* eiam-protocol-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.protocol.jwt.authentication; package cn.topiam.employee.protocol.jwt.authentication;
import java.util.ArrayList; import java.util.ArrayList;
@ -18,7 +35,7 @@ public class JwtLogoutAuthenticationToken extends AbstractAuthenticationToken {
private final Authentication principal; private final Authentication principal;
@Getter @Getter
private final String sessionId; private final String sessionId;
public JwtLogoutAuthenticationToken(Authentication principal, String sessionId) { public JwtLogoutAuthenticationToken(Authentication principal, String sessionId) {
super(new ArrayList<>()); super(new ArrayList<>());
@ -62,7 +79,7 @@ public class JwtLogoutAuthenticationToken extends AbstractAuthenticationToken {
* @return {@code true} if {@link #getPrincipal()} is authenticated, {@code false} otherwise * @return {@code true} if {@link #getPrincipal()} is authenticated, {@code false} otherwise
*/ */
public boolean isPrincipalAuthenticated() { public boolean isPrincipalAuthenticated() {
return !AnonymousAuthenticationToken.class.isAssignableFrom(this.principal.getClass()) && return !AnonymousAuthenticationToken.class.isAssignableFrom(this.principal.getClass())
this.principal.isAuthenticated(); && this.principal.isAuthenticated();
} }
} }

View File

@ -56,7 +56,6 @@ public class JwtRequestAuthenticationToken extends AbstractAuthenticationToken {
@Getter @Getter
private final Map<String, Object> additionalParameters; private final Map<String, Object> additionalParameters;
public JwtRequestAuthenticationToken(Authentication principal, String targetUrl, public JwtRequestAuthenticationToken(Authentication principal, String targetUrl,
JwtProtocolConfig config, JwtProtocolConfig config,
Map<String, Object> additionalParameters) { Map<String, Object> additionalParameters) {

View File

@ -1,17 +1,19 @@
/* /*
* Copyright 2020-2023 the original author or authors. * eiam-protocol-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU Affero General Public License as published by
* You may obtain a copy of the License at * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* https://www.apache.org/licenses/LICENSE-2.0 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* *
* Unless required by applicable law or agreed to in writing, software * You should have received a copy of the GNU Affero General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <http://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package cn.topiam.employee.protocol.jwt.authentication; package cn.topiam.employee.protocol.jwt.authentication;
@ -28,28 +30,25 @@ import org.springframework.security.core.session.SessionRegistry;
*/ */
public final class OidcLogoutAuthenticationProvider implements AuthenticationProvider { public final class OidcLogoutAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JwtLogoutAuthenticationToken logoutAuthenticationToken = (JwtLogoutAuthenticationToken) authentication;
SessionInformation sessionInformation = sessionRegistry
.getSessionInformation(logoutAuthenticationToken.getSessionId());
if (sessionInformation.isExpired()) {
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return JwtLogoutAuthenticationToken.class.isAssignableFrom(authentication);
}
@Override private final SessionRegistry sessionRegistry;
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JwtLogoutAuthenticationToken logoutAuthenticationToken= (JwtLogoutAuthenticationToken) authentication;
SessionInformation sessionInformation=sessionRegistry.getSessionInformation(logoutAuthenticationToken.getSessionId());
if (sessionInformation.isExpired()){
} public OidcLogoutAuthenticationProvider(SessionRegistry sessionRegistry) {
return null; this.sessionRegistry = sessionRegistry;
} }
@Override
public boolean supports(Class<?> authentication) {
return JwtLogoutAuthenticationToken.class.isAssignableFrom(authentication);
}
private final SessionRegistry sessionRegistry;
public OidcLogoutAuthenticationProvider(SessionRegistry sessionRegistry) {
this.sessionRegistry = sessionRegistry;
}
} }

View File

@ -191,12 +191,13 @@ public final class JwtAuthenticationEndpointFilter extends OncePerRequestFilter
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex); this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex);
} catch (Exception ex) { } catch (Exception ex) {
JwtError error = new JwtError(JwtErrorCodes.SERVER_ERROR,ex.getMessage(),JWT_ERROR_URI); JwtError error = new JwtError(JwtErrorCodes.SERVER_ERROR, ex.getMessage(),
JWT_ERROR_URI);
if (this.logger.isTraceEnabled()) { if (this.logger.isTraceEnabled()) {
this.logger.trace(error, ex); this.logger.trace(error, ex);
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new JwtAuthenticationException(error)); new JwtAuthenticationException(error));
} }
} }

View File

@ -1,3 +1,20 @@
/*
* eiam-protocol-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.protocol.jwt.endpoint; package cn.topiam.employee.protocol.jwt.endpoint;
import cn.topiam.employee.protocol.jwt.exception.JwtAuthenticationException; import cn.topiam.employee.protocol.jwt.exception.JwtAuthenticationException;

View File

@ -60,48 +60,48 @@ public final class JwtLogoutAuthenticationEndpointFilter extends OncePerRequestF
/** /**
* *
*/ */
private final RequestMatcher requestMatcher; private final RequestMatcher requestMatcher;
/** /**
* *
*/ */
private AuthenticationFailureHandler authenticationFailureHandler = new JwtAuthenticationFailureHandler(); private AuthenticationFailureHandler authenticationFailureHandler = new JwtAuthenticationFailureHandler();
/** /**
* AuthenticationSuccessHandler * AuthenticationSuccessHandler
*/ */
private AuthenticationSuccessHandler authenticationSuccessHandler=this::sendAuthorizationResponse; private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendAuthorizationResponse;
/** /**
* LogoutHandler * LogoutHandler
*/ */
private final LogoutHandler logoutHandler; private final LogoutHandler logoutHandler;
/** /**
* *
*/ */
private AuthenticationConverter authenticationConverter; private AuthenticationConverter authenticationConverter;
/** /**
* AuthenticationDetailsSource * AuthenticationDetailsSource
*/ */
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource(); private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
/** /**
* *
*/ */
private final AuthenticationManager authenticationManager; private final AuthenticationManager authenticationManager;
public JwtLogoutAuthenticationEndpointFilter(RequestMatcher requestMatcher, public JwtLogoutAuthenticationEndpointFilter(RequestMatcher requestMatcher,
SessionRegistry sessionRegistry, AuthenticationManager authenticationManager) { SessionRegistry sessionRegistry,
AuthenticationManager authenticationManager) {
Assert.notNull(requestMatcher, "requestMatcher cannot be empty"); Assert.notNull(requestMatcher, "requestMatcher cannot be empty");
Assert.notNull(sessionRegistry, "sessionRegistry cannot be empty"); Assert.notNull(sessionRegistry, "sessionRegistry cannot be empty");
Assert.notNull(sessionRegistry, "authenticationManager cannot be empty"); Assert.notNull(sessionRegistry, "authenticationManager cannot be empty");
this.authenticationManager = authenticationManager; this.authenticationManager = authenticationManager;
this.logoutHandler = new SecurityContextLogoutHandler(); this.logoutHandler = new SecurityContextLogoutHandler();
this.requestMatcher = requestMatcher; this.requestMatcher = requestMatcher;
authenticationConverter=new JwtLogoutAuthenticationConverter(); authenticationConverter = new JwtLogoutAuthenticationConverter();
} }
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) { public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
@ -150,13 +150,15 @@ public final class JwtLogoutAuthenticationEndpointFilter extends OncePerRequestF
return; return;
} }
try { try {
Authentication authentication= authenticationConverter.convert(request); Authentication authentication = authenticationConverter.convert(request);
if (authentication instanceof AbstractAuthenticationToken) { if (authentication instanceof AbstractAuthenticationToken) {
((AbstractAuthenticationToken) authentication) ((AbstractAuthenticationToken) authentication)
.setDetails(this.authenticationDetailsSource.buildDetails(request)); .setDetails(this.authenticationDetailsSource.buildDetails(request));
} }
Authentication authenticationResult= authenticationManager.authenticate(authentication); Authentication authenticationResult = authenticationManager
authenticationSuccessHandler.onAuthenticationSuccess(request,response,authenticationResult); .authenticate(authentication);
authenticationSuccessHandler.onAuthenticationSuccess(request, response,
authenticationResult);
} catch (JwtAuthenticationException ex) { } catch (JwtAuthenticationException ex) {
if (this.logger.isTraceEnabled()) { if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.format("JWT logout request failed: %s", ex.getError()), this.logger.trace(LogMessage.format("JWT logout request failed: %s", ex.getError()),
@ -164,16 +166,16 @@ public final class JwtLogoutAuthenticationEndpointFilter extends OncePerRequestF
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex); this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex);
} catch (Exception ex) { } catch (Exception ex) {
JwtError error = new JwtError(JwtErrorCodes.SERVER_ERROR,ex.getMessage(),JWT_ERROR_URI); JwtError error = new JwtError(JwtErrorCodes.SERVER_ERROR, ex.getMessage(),
JWT_ERROR_URI);
if (this.logger.isTraceEnabled()) { if (this.logger.isTraceEnabled()) {
this.logger.trace(error, ex); this.logger.trace(error, ex);
} }
this.authenticationFailureHandler.onAuthenticationFailure(request, response, this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new JwtAuthenticationException(error)); new JwtAuthenticationException(error));
} }
} }
/** /**
* *
* *
@ -183,13 +185,13 @@ public final class JwtLogoutAuthenticationEndpointFilter extends OncePerRequestF
*/ */
private void sendAuthorizationResponse(HttpServletRequest request, HttpServletResponse response, private void sendAuthorizationResponse(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) { Authentication authentication) {
JwtLogoutAuthenticationToken jwtLogoutAuthentication= (JwtLogoutAuthenticationToken) authentication; JwtLogoutAuthenticationToken jwtLogoutAuthentication = (JwtLogoutAuthenticationToken) authentication;
// Check for active user session // Check for active user session
if (jwtLogoutAuthentication.isPrincipalAuthenticated() && if (jwtLogoutAuthentication.isPrincipalAuthenticated()
StringUtils.hasText(jwtLogoutAuthentication.getSessionId())) { && StringUtils.hasText(jwtLogoutAuthentication.getSessionId())) {
// Perform logout // Perform logout
this.logoutHandler.logout(request, response, this.logoutHandler.logout(request, response,
(Authentication) jwtLogoutAuthentication.getPrincipal()); (Authentication) jwtLogoutAuthentication.getPrincipal());
} }
} }

View File

@ -1,17 +1,19 @@
/* /*
* Copyright 2020-2023 the original author or authors. * eiam-protocol-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU Affero General Public License as published by
* You may obtain a copy of the License at * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* https://www.apache.org/licenses/LICENSE-2.0 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* *
* Unless required by applicable law or agreed to in writing, software * You should have received a copy of the GNU Affero General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <http://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package cn.topiam.employee.protocol.jwt.endpoint.authentication; package cn.topiam.employee.protocol.jwt.endpoint.authentication;
@ -37,31 +39,31 @@ import static cn.topiam.employee.protocol.jwt.endpoint.JwtAuthenticationEndpoint
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2023/9/4 16:01 * Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2023/9/4 16:01
*/ */
public final class JwtLogoutAuthenticationConverter implements AuthenticationConverter { public final class JwtLogoutAuthenticationConverter implements AuthenticationConverter {
private static final Authentication ANONYMOUS_AUTHENTICATION = new AnonymousAuthenticationToken( private static final Authentication ANONYMOUS_AUTHENTICATION = new AnonymousAuthenticationToken(
"anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")); "anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
@Override @Override
public Authentication convert(HttpServletRequest request) { public Authentication convert(HttpServletRequest request) {
if (request.getParameterValues(S_ID).length != 1) { if (request.getParameterValues(S_ID).length != 1) {
throwError(new JwtError(OAuth2ErrorCodes.INVALID_REQUEST, throwError(new JwtError(OAuth2ErrorCodes.INVALID_REQUEST,
"JWT Logout Request Parameter: " + S_ID)); "JWT Logout Request Parameter: " + S_ID));
} }
String sessionId = request.getParameter(S_ID); String sessionId = request.getParameter(S_ID);
if (!StringUtils.hasText(sessionId)) { if (!StringUtils.hasText(sessionId)) {
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
if (session != null) { if (session != null) {
sessionId = session.getId(); sessionId = session.getId();
} }
} }
Authentication principal = SecurityContextHolder.getContext().getAuthentication(); Authentication principal = SecurityContextHolder.getContext().getAuthentication();
if (principal == null) { if (principal == null) {
principal = ANONYMOUS_AUTHENTICATION; principal = ANONYMOUS_AUTHENTICATION;
} }
return new JwtLogoutAuthenticationToken(principal,sessionId); return new JwtLogoutAuthenticationToken(principal, sessionId);
} }
} }