Spring Security面试题
基础概念
Q1: Spring Security的核心功能有哪些?
public class SecurityBasicDemo {
public class SecurityConfigExample {
public void configDemo() {
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("password"))
.roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
}
}
public class AuthenticationExample {
public void authDemo() {
@Component
public class CustomAuthenticationProvider
implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
String username = auth.getName();
String password = auth.getCredentials().toString();
if (validateUser(username, password)) {
List<GrantedAuthority> authorities =
Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
return new UsernamePasswordAuthenticationToken(
username, password, authorities);
}
throw new BadCredentialsException("Invalid credentials");
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(
UsernamePasswordAuthenticationToken.class);
}
}
}
}
}
Q2: Spring Security的认证和授权机制是怎样的?
public class AuthenticationAuthorizationDemo {
public class AuthenticationMechanismExample {
public void authMechanismDemo() {
@Service
public class CustomUserDetailsService
implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
getAuthorities(user.getRoles()));
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return roles.stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList());
}
}
}
}
public class AuthorizationMechanismExample {
public void authorizationDemo() {
@Configuration
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class MethodSecurityConfig
extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(
new CustomPermissionEvaluator());
return expressionHandler;
}
}
@Service
public class UserService {
@PreAuthorize("hasRole('ADMIN')")
public void createUser(User user) {
}
@PostAuthorize("returnObject.username == authentication.name")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
}
}
}
}
高级特性
Q3: Spring Security的OAuth2.0实现是怎样的?
public class OAuth2Demo {
public class AuthorizationServerExample {
public void authServerDemo() {
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig
extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(
ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("client")
.secret(passwordEncoder.encode("secret"))
.authorizedGrantTypes(
"authorization_code",
"password",
"client_credentials",
"refresh_token")
.scopes("read", "write")
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(86400);
}
@Override
public void configure(
AuthorizationServerSecurityConfigurer security) {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
}
}
}
public class ResourceServerExample {
public void resourceServerDemo() {
@Configuration
@EnableResourceServer
public class ResourceServerConfig
extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll()
.and()
.cors()
.and()
.csrf().disable();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("resource_id");
}
}
}
}
}
Q4: Spring Security的会话管理是怎样的?
public class SessionManagementDemo {
public class SessionConfigExample {
public void sessionConfigDemo() {
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login?expired")
.and()
.sessionFixation()
.migrateSession()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
}
}
public class SessionEventExample {
public void sessionEventDemo() {
@Component
public class SecurityEventListener
implements ApplicationListener<AbstractAuthenticationEvent> {
@Override
public void onApplicationEvent(
AbstractAuthenticationEvent event) {
if (event instanceof AuthenticationSuccessEvent) {
logAuthenticationSuccess(event);
} else if (event instanceof AuthenticationFailureEvent) {
logAuthenticationFailure(event);
} else if (event instanceof InteractiveAuthenticationSuccessEvent) {
logInteractiveAuthenticationSuccess(event);
}
}
}
}
}
}
Q5: Spring Security的安全防护有哪些?
public class SecurityProtectionDemo {
public class CSRFProtectionExample {
public void csrfDemo() {
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/api/webhook/**");
}
}
@Component
public class CSRFTokenHandler extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
response.setHeader("X-CSRF-TOKEN", csrf.getToken());
}
filterChain.doFilter(request, response);
}
}
}
}
public class XSSProtectionExample {
public void xssDemo() {
@Component
public class XSSFilter implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
XSSRequestWrapper wrappedRequest =
new XSSRequestWrapper((HttpServletRequest) request);
chain.doFilter(wrappedRequest, response);
}
}
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
private String cleanXSS(String value) {
return value.replaceAll("<", "<")
.replaceAll(">", ">");
}
}
}
}
public class SQLInjectionProtectionExample {
public void sqlInjectionDemo() {
@Repository
public class UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public User findByUsername(String username) {
return jdbcTemplate.queryForObject(
"SELECT * FROM users WHERE username = ?",
new Object[]{username},
(rs, rowNum) ->
new User(
rs.getLong("id"),
rs.getString("username"),
rs.getString("password")
)
);
}
}
@Component
public class InputValidator {
public boolean isValidInput(String input) {
return input != null &&
input.matches("[a-zA-Z0-9_]+");
}
}
}
}
}
面试关键点
- 理解Spring Security的核心功能
- 掌握认证和授权机制
- 熟悉OAuth2.0的实现
- 了解会话管理机制
- 理解安全防护措施
- 掌握配置和扩展方法
- 注意性能和安全平衡
- 关注最佳实践