此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
Servlet 2.5+ 集成
本节描述了 Spring Security 如何与 Servlet 2.5 规范集成。
HttpServletRequest.getRemoteUser()
HttpServletRequest.getRemoteUser()
返回 的结果,通常是当前用户名。如果要在应用程序中显示当前用户名,这可能很有用。
此外,您还可以检查此字段是否为 null,以确定用户是否已进行身份验证或匿名。
了解用户是否经过身份验证有助于确定是否应显示某些 UI 元素(例如,仅当用户经过身份验证时才应显示注销链接)。SecurityContextHolder.getContext().getAuthentication().getName()
HttpServletRequest.getUserPrincipal()
HttpServletRequest.getUserPrincipal()
返回 的结果。
这意味着它是一个 ,通常是使用基于用户名和密码的身份验证时的实例。
如果您需要有关用户的其他信息,这可能很有用。
例如,您可能已创建一个自定义,该自定义返回包含用户的名字和姓氏的自定义。
您可以通过以下方式获取此信息:SecurityContextHolder.getContext().getAuthentication()
Authentication
UsernamePasswordAuthenticationToken
UserDetailsService
UserDetails
-
Java
-
Kotlin
Authentication auth = httpServletRequest.getUserPrincipal();
// assume integrated custom UserDetails called MyCustomUserDetails
// by default, typically instance of UserDetails
MyCustomUserDetails userDetails = (MyCustomUserDetails) auth.getPrincipal();
String firstName = userDetails.getFirstName();
String lastName = userDetails.getLastName();
val auth: Authentication = httpServletRequest.getUserPrincipal()
// assume integrated custom UserDetails called MyCustomUserDetails
// by default, typically instance of UserDetails
val userDetails: MyCustomUserDetails = auth.principal as MyCustomUserDetails
val firstName: String = userDetails.firstName
val lastName: String = userDetails.lastName
应该注意的是,在整个应用程序中执行如此多的 logic 通常是不好的做法。 相反,应该将其集中以减少 Spring Security 和 Servlet API 的任何耦合。 |
HttpServletRequest.isUserInRole(字符串)
HttpServletRequest.isUserInRole(String)
确定是否包含传递给 的角色。
通常,用户不应将前缀传递给此方法,因为它是自动添加的。
例如,如果要确定当前用户是否具有“ROLE_ADMIN”权限,则可以使用以下内容:SecurityContextHolder.getContext().getAuthentication().getAuthorities()
GrantedAuthority
isUserInRole(String)
ROLE_
-
Java
-
Kotlin
boolean isAdmin = httpServletRequest.isUserInRole("ADMIN");
val isAdmin: Boolean = httpServletRequest.isUserInRole("ADMIN")
这对于确定是否应显示某些 UI 组件可能很有用。 例如,只有当当前用户是管理员时,您才可以显示管理员链接。
应该注意的是,在整个应用程序中执行如此多的 logic 通常是不好的做法。 相反,应该将其集中以减少 Spring Security 和 Servlet API 的任何耦合。 |
Servlet 3+ 集成
以下部分描述了 Spring Security 与之集成的 Servlet 3 方法。
HttpServletRequest.authenticate(HttpServletResponse)
您可以使用 HttpServletRequest.authenticate(HttpServletResponse)
方法确保用户已经过身份验证。
如果他们未通过身份验证,则 configured 用于请求用户进行身份验证(重定向到登录页面)。AuthenticationEntryPoint
HttpServletRequest.login(字符串,字符串)
您可以使用 HttpServletRequest.login(String,String)
方法使用当前的 .
例如,以下将尝试使用用户名 of 和密码 :AuthenticationManager
user
password
-
Java
-
Kotlin
try {
httpServletRequest.login("user","password");
} catch(ServletException ex) {
// fail to authenticate
}
try {
httpServletRequest.login("user", "password")
} catch (ex: ServletException) {
// fail to authenticate
}
如果您希望 Spring Security 处理失败的身份验证尝试,则无需捕获。 |
HttpServletRequest.logout()
你可以使用 HttpServletRequest.logout()
方法注销当前用户。
通常,这意味着 被清除、失效、任何 “Remember Me” 身份验证被清理,依此类推。
但是,配置的实现会有所不同,具体取决于您的 Spring Security 配置。
请注意,在 has called 之后,您仍然负责写出响应。
通常,这将涉及重定向到欢迎页面。SecurityContextHolder
HttpSession
LogoutHandler
HttpServletRequest.logout()
AsyncContext.start(可运行)
AsyncContext.start(Runnable)
方法可确保您的凭证传播到新的 .
通过使用 Spring Security 的并发支持,Spring Security 会覆盖以确保在处理 Runnable 时使用 current。
以下示例输出当前用户的 Authentication:Thread
AsyncContext.start(Runnable)
SecurityContext
-
Java
-
Kotlin
final AsyncContext async = httpServletRequest.startAsync();
async.start(new Runnable() {
public void run() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
try {
final HttpServletResponse asyncResponse = (HttpServletResponse) async.getResponse();
asyncResponse.setStatus(HttpServletResponse.SC_OK);
asyncResponse.getWriter().write(String.valueOf(authentication));
async.complete();
} catch(Exception ex) {
throw new RuntimeException(ex);
}
}
});
val async: AsyncContext = httpServletRequest.startAsync()
async.start {
val authentication: Authentication = SecurityContextHolder.getContext().authentication
try {
val asyncResponse = async.response as HttpServletResponse
asyncResponse.status = HttpServletResponse.SC_OK
asyncResponse.writer.write(String.valueOf(authentication))
async.complete()
} catch (ex: Exception) {
throw RuntimeException(ex)
}
}
异步 Servlet 支持
如果您使用基于 Java 的配置,则可以开始了。
如果您使用 XML 配置,则需要进行一些更新。
第一步是确保您已更新文件以至少使用 3.0 架构:web.xml
<web-app 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 https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
接下来,您需要确保已设置为处理异步请求:springSecurityFilterChain
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ASYNC</dispatcher>
</filter-mapping>
现在 Spring Security 确保 YOUR 也在异步请求上传播。SecurityContext
那么它是如何工作的呢?如果您不是真的感兴趣,请随时跳过本节的其余部分
其中大部分都内置在 Servlet 规范中,但 Spring Security 会进行一些调整,以确保异步请求正常工作。
在 Spring Security 3.2 之前,一旦提交,就会自动保存 from 。
这可能会导致异步环境中出现问题。
请考虑以下示例:SecurityContext
SecurityContextHolder
HttpServletResponse
-
Java
-
Kotlin
httpServletRequest.startAsync();
new Thread("AsyncThread") {
@Override
public void run() {
try {
// Do work
TimeUnit.SECONDS.sleep(1);
// Write to and commit the httpServletResponse
httpServletResponse.getOutputStream().flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
httpServletRequest.startAsync()
object : Thread("AsyncThread") {
override fun run() {
try {
// Do work
TimeUnit.SECONDS.sleep(1)
// Write to and commit the httpServletResponse
httpServletResponse.outputStream.flush()
} catch (ex: java.lang.Exception) {
ex.printStackTrace()
}
}
}.start()
问题是 Spring Security 不知道这一点,因此 不会传播到它。
这意味着,当我们提交 时,没有 .
当 Spring Security 自动保存提交时,它将丢失已登录的用户。Thread
SecurityContext
HttpServletResponse
SecurityContext
SecurityContext
HttpServletResponse
从版本 3.2 开始,Spring Security 已经足够智能,不再自动保存 on 提交 一旦被调用。SecurityContext
HttpServletResponse
HttpServletRequest.startAsync()
如果您希望 Spring Security 处理失败的身份验证尝试,则无需捕获。 |
Servlet 3.1+ 集成
以下部分描述了 Spring Security 与之集成的 Servlet 3.1 方法。
HttpServletRequest#changeSessionId()
HttpServletRequest.changeSessionId() 是 Servlet 3.1 及更高版本中防止会话固定攻击的默认方法。