Skip to main content
 首页 » 编程设计

spring security 获取用户信息

2022年07月19日142cloudgamer

spring security 获取用户信息

本文描述在spring security中如何获取用户信息。分别介绍几种常用的方法实现。

通过Bean获取用户

获取当前认证用户(authenticated principal)最简单的方式是通过SecurityContextHolder类的静态方法:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
String currentPrincipalName = authentication.getName(); 

下面是改进版本代码,获取前首先检查是否存在认证用户:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
if (!(authentication instanceof AnonymousAuthenticationToken)) { 
    String currentUserName = authentication.getName(); 
    return currentUserName; 
} 

当然,静态调用的缺点是代码的可测试性明显降低。我们继续探索新的方式实现。

在控制器中获取用户

在@Controller 注解的bean里,有额外的选项。principal 可以直接作为方法参数,框架会自动赋值。

import java.security.Principal; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
  
@Controller 
public class SecurityController { 
  
    @RequestMapping(value = "/username", method = RequestMethod.GET) 
    @ResponseBody 
    public String currentUserName(Principal principal) { 
        return principal.getName(); 
    } 
} 

或者也可以使用认证信息:

import org.springframework.security.core.Authentication; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
  
@Controller 
public class SecurityController { 
  
    @RequestMapping(value = "/username", method = RequestMethod.GET) 
    @ResponseBody 
    public String currentUserName(Authentication authentication) { 
        return authentication.getName(); 
    } 
} 

框架为了尽可能的灵活,Authentication 类的API很方便使用。因此,通过转换可以返回principal对象。

UserDetails userDetails = (UserDetails) authentication.getPrincipal(); 
System.out.println("User has authorities: " + userDetails.getAuthorities()); 

最后一种方式直接通过http request:

import java.security.Principal; 
  
import javax.servlet.http.HttpServletRequest; 
  
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
  
@Controller 
public class SecurityController { 
  
    @RequestMapping(value = "/username", method = RequestMethod.GET) 
    @ResponseBody 
    public String currentUserNameSimple(HttpServletRequest request) { 
        Principal principal = request.getUserPrincipal(); 
        return principal.getName(); 
    } 
} 

通过自定义接口获取用户信息

为了充分利用spring的依赖注入功能,可以在在任何地方获取认证信息,不仅仅是@Controller注解的bean,我们通过简单的门面隐藏静态访问:

public interface IAuthenticationFacade { 
    Authentication getAuthentication(); 
} 
 
@Component 
public class AuthenticationFacade implements IAuthenticationFacade { 
  
    @Override 
    public Authentication getAuthentication() { 
        return SecurityContextHolder.getContext().getAuthentication(); 
    } 
} 

该门面暴露了认证对象并隐藏静态访问代码,让业务解耦并方便测试:

@Controller 
public class SecurityController { 
    @Autowired 
    private IAuthenticationFacade authenticationFacade; 
  
    @RequestMapping(value = "/username", method = RequestMethod.GET) 
    @ResponseBody 
    public String currentUserNameSimple() { 
        Authentication authentication = authenticationFacade.getAuthentication(); 
        return authentication.getName(); 
    } 
} 

在jsp中获取用户信息

当前认证用户也可以在jsp页面中获取到。利用spring security标签支持。首先我们需要在页面中定义标签:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> 

然后,我们可以引用principal:

<security:authorize access="isAuthenticated()"> 
    authenticated as <security:authentication property="principal.username" />  
</security:authorize> 

总计

本文说明在spring应用中如何获取用户信息,开始介绍了通用的静态方法访问机制,后面提供了几种更好的注入方式获取principal。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/79337478