gpt4 book ai didi

java - 基于注释的 Spring Security REST API

转载 作者:行者123 更新时间:2023-12-01 10:10:44 24 4
gpt4 key购买 nike

我一直在尝试创建一个使用 Spring security 保护的 REST API

有关架构详细信息,请参阅此链接:Spring Security with REST architecture

但是,在我的实现过程中,我面临以下问题:

Exception starting filter springSecurityFilterChain

我的应用程序实现如下:

@EnableWebMvc
@Configuration
@ComponentScan({ "com.ws.service.*" })
public class AppConfig extends Application {
...
}

自定义 JDBCDaoImpl

public class CustomJDBCDaoImpl extends JdbcDaoImpl {

public CustomJDBCDaoImpl() {
// TODO Auto-generated constructor stub
super();

}

private DataSource getDataSourceFromJndi() {
...
}

@Override
protected List<GrantedAuthority> loadGroupAuthorities(String username) {
...
}

@Override
public UserDetails loadUserByUsername(String username) {
...
}

private UpUser findUserByScreenName(String userName) {
...
}

private ResultSet executeQuery(String sql){
...
}
}

Source code for Stateless Authentication Filter

无状态身份验证安全配置

@EnableWebSecurity
@Configuration
@Order(1)
public class StatelessAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired
private TokenAuthenticationService tokenAuthenticationService;

public StatelessAuthenticationSecurityConfig() {
super(true);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.headers().cacheControl().and()
.authorizeRequests()

//allow anonymous resource requests
.antMatchers("/").permitAll()
.antMatchers("/favicon.ico").permitAll()
.antMatchers("/resources/**").permitAll()

//allow anonymous POSTs to login
.antMatchers(HttpMethod.POST, "/api/login").permitAll()

//allow anonymous GETs to API
.antMatchers(HttpMethod.GET, "/api/**").permitAll()

//defined Admin only API area
.antMatchers("/admin/**").hasRole("ADMIN")

//all other request need to be authenticated
.anyRequest().hasRole("USER").and()

// custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
.addFilterBefore(new StatelessLoginFilter("/api/login", tokenAuthenticationService, new CustomJDBCDaoImpl(), authenticationManager()), UsernamePasswordAuthenticationFilter.class)

// custom Token based authentication based on the header previously given to the client
.addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class);
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new CustomJDBCDaoImpl()).passwordEncoder(new BCryptPasswordEncoder());
}


}

无状态登录过滤器

class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter {

private final TokenAuthenticationService tokenAuthenticationService;
private final CustomJDBCDaoImpl userDetailsService;

protected StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService,
CustomJDBCDaoImpl userDetailsService, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(urlMapping));
this.userDetailsService = userDetailsService;
this.tokenAuthenticationService = tokenAuthenticationService;
setAuthenticationManager(authManager);
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {

final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(
request.getParameter("username").toString(), request.getParameter("password").toString());
return getAuthenticationManager().authenticate(loginToken);
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authentication) throws IOException, ServletException {

// Lookup the complete User object from the database and create an Authentication for it
final UserDetails authenticatedUser = userDetailsService.loadUserByUsername(authentication.getName());
final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser);

// Add the custom token as HTTP header to the response
tokenAuthenticationService.addAuthentication(response, userAuthentication);

// Add the authentication to the Security context
SecurityContextHolder.getContext().setAuthentication(userAuthentication);
}
}

<强> Source Code for Token Authentication Service

<强> Source Code for Token Handler

此外,它还直接将我重定向到该服务,而不是向我显示输入用户名和密码的对话框。

最佳答案

我有类似的设置。不同的是,我有一个额外的 ContextLoaderListener 来加载 SpringSecurityFilerChain

@WebListener
public class SpringContextLoader extends ContextLoaderListener {

@Override
protected WebApplicationContext createWebApplicationContext(final ServletContext sc) {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(SpringConfiguration.class);

sc.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")).addMappingForUrlPatterns(null, false, "/*");

Dynamic dynamic = sc.addServlet("dispatcher", new DispatcherServlet(applicationContext));
dynamic.addMapping("/");
dynamic.setLoadOnStartup(1);

return applicationContext;
}
}

关于java - 基于注释的 Spring Security REST API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36140375/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com