Skip to content

Commit

Permalink
代码优化
Browse files Browse the repository at this point in the history
  • Loading branch information
smthing committed Aug 17, 2024
1 parent d8aa3fc commit d12c864
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import jakarta.servlet.DispatcherType;
import jakarta.servlet.ServletContainerInitializer;
import jakarta.servlet.annotation.HandlesTypes;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.HttpMethodConstraint;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.annotation.WebInitParam;
Expand All @@ -21,6 +23,7 @@
import org.smartboot.http.common.utils.StringUtils;
import tech.smartboot.servlet.conf.FilterInfo;
import tech.smartboot.servlet.conf.FilterMappingInfo;
import tech.smartboot.servlet.conf.SecurityConstraint;
import tech.smartboot.servlet.conf.ServletInfo;
import tech.smartboot.servlet.conf.ServletMappingInfo;
import tech.smartboot.servlet.enums.FilterMappingType;
Expand Down Expand Up @@ -274,9 +277,25 @@ private void checkAnnotation(JavaClass javaClass, Map<String, JavaClassCacheEntr
servletMappings.add(new ServletMappingInfo(name, url));
}
ServletSecurity servletSecurity = clazz.getAnnotation(ServletSecurity.class);
// if (servletSecurity != null) {
// servletSecurity.value()
// }
if (servletSecurity != null) {
if (servletSecurity.httpMethodConstraints().length > 0) {
for (HttpMethodConstraint httpMethodConstraint : servletSecurity.httpMethodConstraints()) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.getHttpMethods().add(httpMethodConstraint.value());
securityConstraint.setEmptyRoleSemantic(httpMethodConstraint.emptyRoleSemantic());
securityConstraint.setTransportGuarantee(httpMethodConstraint.transportGuarantee());
securityConstraint.setRoleNames(Arrays.asList(httpMethodConstraint.rolesAllowed()));
servletInfo.getSecurityConstraints().add(securityConstraint);
}
} else {
HttpConstraint httpConstraint = servletSecurity.value();
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setEmptyRoleSemantic(httpConstraint.value());
securityConstraint.setTransportGuarantee(httpConstraint.transportGuarantee());
securityConstraint.setRoleNames(Arrays.asList(httpConstraint.rolesAllowed()));
servletInfo.getSecurityConstraints().add(securityConstraint);
}
}
servlets.add(servletInfo);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import jakarta.servlet.DispatcherType;
import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.annotation.ServletSecurity;
import org.smartboot.http.common.utils.NumberUtils;
import org.smartboot.http.common.utils.StringUtils;
import org.w3c.dom.Document;
Expand Down Expand Up @@ -373,12 +374,17 @@ private void parseSecurityConstraint(WebAppInfo webAppInfo, Element parentElemen

Node authConstraint = getChildNode(node, "auth-constraint");
if (authConstraint != null) {
securityConstraint.getRoleNames().addAll(getNodeValues(authConstraint, "role-name"));
securityConstraint.setRoleNames(getNodeValues(authConstraint, "role-name"));
}

Node userDataConstraint = getChildNode(node, "user-data-constraint");
if (userDataConstraint != null) {
securityConstraint.getTransportGuarantees().addAll(getNodeValues(userDataConstraint, "transport-guarantee"));
String transportGuarantees = getNodeValue(userDataConstraint, Collections.singletonList("transport-guarantee")).get("transport-guarantee");
if ("CONFIDENTIAL".equals(transportGuarantees)) {
securityConstraint.setTransportGuarantee(ServletSecurity.TransportGuarantee.CONFIDENTIAL);
} else {
securityConstraint.setTransportGuarantee(ServletSecurity.TransportGuarantee.NONE);
}
}
webAppInfo.getSecurityConstraints().add(securityConstraint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@

package tech.smartboot.servlet.conf;

import jakarta.servlet.annotation.ServletSecurity;

import java.util.ArrayList;
import java.util.List;

public class SecurityConstraint {
private ServletSecurity.EmptyRoleSemantic emptyRoleSemantic = ServletSecurity.EmptyRoleSemantic.PERMIT;
private ServletSecurity.TransportGuarantee transportGuarantee = ServletSecurity.TransportGuarantee.NONE;
// private final List<String> resourceNames = new ArrayList<>();
private final List<UrlPattern> urlPatterns = new ArrayList<>();
private final List<String> httpMethods = new ArrayList<>();

private final List<String> roleNames = new ArrayList<>();
private final List<String> transportGuarantees = new ArrayList<>();
private List<String> roleNames;

public List<UrlPattern> getUrlPatterns() {
return urlPatterns;
Expand All @@ -33,7 +36,23 @@ public List<String> getRoleNames() {
return roleNames;
}

public List<String> getTransportGuarantees() {
return transportGuarantees;
public void setRoleNames(List<String> roleNames) {
this.roleNames = roleNames;
}

public ServletSecurity.EmptyRoleSemantic getEmptyRoleSemantic() {
return emptyRoleSemantic;
}

public void setEmptyRoleSemantic(ServletSecurity.EmptyRoleSemantic emptyRoleSemantic) {
this.emptyRoleSemantic = emptyRoleSemantic;
}

public ServletSecurity.TransportGuarantee getTransportGuarantee() {
return transportGuarantee;
}

public void setTransportGuarantee(ServletSecurity.TransportGuarantee transportGuarantee) {
this.transportGuarantee = transportGuarantee;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import tech.smartboot.servlet.impl.ServletContextImpl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
Expand All @@ -49,6 +51,7 @@ public class ServletInfo {

private boolean asyncSupported;
private boolean init = false;
private List<SecurityConstraint> securityConstraints = new ArrayList<>();

public synchronized void init(ServletContextImpl servletContext) {
if (init) {
Expand Down Expand Up @@ -176,6 +179,10 @@ public Map<String, String> getSecurityRoles() {
return securityRoles;
}

public List<SecurityConstraint> getSecurityConstraints() {
return securityConstraints;
}

/**
* 是否已经完成初始化
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,68 @@
import jakarta.servlet.http.HttpServletResponse;
import tech.smartboot.servlet.conf.SecurityConstraint;
import tech.smartboot.servlet.conf.UrlPattern;
import tech.smartboot.servlet.plugins.security.UserTO;
import tech.smartboot.servlet.util.PathMatcherUtil;

import java.io.IOException;
import java.util.List;

public class SecurityHandler extends Handler {
@Override
public void handleRequest(HandlerContext handlerContext) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) handlerContext.getRequest();
for (SecurityConstraint securityConstraint : handlerContext.getServletContext().getDeploymentInfo().getSecurityConstraints()) {
boolean match = false;
for (UrlPattern urlPattern : securityConstraint.getUrlPatterns()) {
if (PathMatcherUtil.matches((HttpServletRequest) handlerContext.getRequest(), urlPattern)) {
match = true;
break;
// UserTO userTO = null;
// if (!handlerContext.getServletInfo().getSecurityRoles().isEmpty()) {
// userTO = handlerContext.getServletContext().getRuntime().getSecurityProvider().getUser(request);
// if (userTO == null) {
// ((HttpServletResponse) handlerContext.getResponse()).sendError(403);
// return;
// }
// boolean valid = false;
// for (String role : handlerContext.getServletInfo().getSecurityRoles().values()) {
// if (userTO.getRoles().contains(role)) {
// valid = true;
// break;
// }
// }
// if (!valid) {
// ((HttpServletResponse) handlerContext.getResponse()).sendError(403);
// return;
// }
// }

List<SecurityConstraint> constraints = handlerContext.getServletInfo().getSecurityConstraints();
if (constraints.isEmpty()) {
constraints = handlerContext.getServletContext().getDeploymentInfo().getSecurityConstraints().stream().filter(securityConstraint -> {
for (UrlPattern urlPattern : securityConstraint.getUrlPatterns()) {
if (PathMatcherUtil.matches((HttpServletRequest) handlerContext.getRequest(), urlPattern)) {
return true;
}
}
return false;
}).toList();
}
if (constraints.isEmpty()) {
doNext(handlerContext);
return;
}
constraints = constraints.stream().filter(securityConstraint -> securityConstraint.getRoleNames() == null || securityConstraint.getHttpMethods().isEmpty() || securityConstraint.getHttpMethods().contains(request.getMethod())).toList();
if (constraints.isEmpty()) {
((HttpServletResponse) handlerContext.getResponse()).sendError(403);
return;
}
UserTO userTO = handlerContext.getServletContext().getRuntime().getSecurityProvider().getUser(request);
constraints = constraints.stream().filter(securityConstraint -> {
for (String role : securityConstraint.getRoleNames()) {
if (userTO.getRoles().contains(role)) {
return true;
}
}
if (!match) {
continue;
}
if (!securityConstraint.getHttpMethods().isEmpty() && !securityConstraint.getHttpMethods().contains(request.getMethod())) {
((HttpServletResponse) handlerContext.getResponse()).sendError(403);
return;
}
return false;
}).toList();
if (constraints.isEmpty()) {
((HttpServletResponse) handlerContext.getResponse()).sendError(403);
return;
}
doNext(handlerContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,31 @@
package tech.smartboot.servlet.plugins.security;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.smartboot.http.common.utils.StringUtils;
import tech.smartboot.servlet.conf.SecurityConstraint;
import tech.smartboot.servlet.impl.HttpServletRequestImpl;
import tech.smartboot.servlet.provider.SecurityProvider;

import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SecurityProviderImpl implements SecurityProvider {
private Map<String, SecurityTO> exactPathSecurities = new HashMap<>();
private Map<String, SecurityTO> prefixPathSecurities = new HashMap<>();
private Map<String, SecurityTO> extensionSecurities = new HashMap<>();
private Map<String, SecurityTO> methodSecurities = new HashMap<>();
private final Map<String, UserTO> headerSecurities = new HashMap<>();

@Override
public void addUser(String username, String password, Set<String> roles) {
headerSecurities.put(username, new UserTO(username, password, roles));
}

@Override
public void init(List<SecurityConstraint> constraints) {
Expand All @@ -50,4 +61,18 @@ public boolean isUserInRole(String role, HttpServletRequestImpl httpServletReque
public void logout(HttpServletRequestImpl httpServletRequest) throws ServletException {

}

@Override
public UserTO getUser(HttpServletRequest request) {
String authorization = request.getHeader("Authorization");
if (StringUtils.isBlank(authorization)) {
return null;
}
UserTO userTO = new UserTO("j2ee", "j2ee", Set.of("Administrator", "Employee"));
if (authorization.startsWith("Basic ")) {
System.out.println(new String(Base64.getDecoder().decode(authorization.substring(6))));

}
return userTO;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) [2022] smartboot [zhengjunweimail@163.com]
*
* 企业用户未经smartboot组织特别许可,需遵循AGPL-3.0开源协议合理合法使用本项目。
*
* Enterprise users are required to use this project reasonably
* and legally in accordance with the AGPL-3.0 open source agreement
* without special permission from the smartboot organization.
*/

package tech.smartboot.servlet.plugins.security;

import java.util.Set;

public class UserTO {
private String username;
private String password;
private Set<String> roles;

public UserTO(String username, String password, Set<String> roles) {
this.username = username;
this.password = password;
this.roles = roles;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Set<String> getRoles() {
return roles;
}

public void setRoles(Set<String> roles) {
this.roles = roles;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@
package tech.smartboot.servlet.provider;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import tech.smartboot.servlet.conf.SecurityConstraint;
import tech.smartboot.servlet.impl.HttpServletRequestImpl;
import tech.smartboot.servlet.plugins.security.UserTO;

import java.io.IOException;
import java.util.List;
import java.util.Set;

public interface SecurityProvider {
void addUser(String username, String password, Set<String> roles);

void init(List<SecurityConstraint> constraints);

public void login(String username, String password, HttpServletRequestImpl httpServletRequest) throws ServletException;
Expand All @@ -29,4 +34,6 @@ public interface SecurityProvider {


public void logout(HttpServletRequestImpl httpServletRequest) throws ServletException;

public UserTO getUser(HttpServletRequest request);
}

0 comments on commit d12c864

Please sign in to comment.