当前位置: 首页 > 知识库问答 >
问题:

使用REST API的Spring Security性

谷梁星雨
2023-03-14

  1. 请求可以从任何平台发送到“abc.com/rest_api/”
  2. 请求将发送到点3或点5。如果用户已通过用户名和密码进行身份验证,则将根据令牌验证请求,否则将重定向到数据库。
  3. 如果用户名和密码必须由数据库进行身份验证,则将生成一个令牌并作为响应发回。
  4. 之后,只有基于令牌的身份验证才能工作。

我试图创建一个基本的结构,我想一定是犯了一个小错误,因为它没有像预期的那样工作。

@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled=true)
public class UserDetailsSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private NSecurityContextHolder securityContextHolder;

    @Autowired
    private NHttpServletRequestBinder<Authentication> authenticationBinder;

    public static final String DEF_USERS_BY_USERNAME_QUERY
            = "SELECT user ";


public static final String GROUPS_BY_USERNAME_QUERY =
        "SELECT groups by user";
public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY =
        "SELECT  authorities";


@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.jdbcAuthentication().dataSource(getDataSourceFromJndi())
                .usersByUsernameQuery(DEF_USERS_BY_USERNAME_QUERY).
                authoritiesByUsernameQuery(DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY).
                groupAuthoritiesByUsername(GROUPS_BY_USERNAME_QUERY);


    }
      private DataSource getDataSourceFromJndi() {
        try {


             DataSource dataSource = (DataSource) new InitialContext().lookup("DS");
            return dataSource;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.jdbcAuthentication().dataSource(getDataSourceFromJndi())
                .usersByUsernameQuery(DEF_USERS_BY_USERNAME_QUERY).
                authoritiesByUsernameQuery(DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY).
                groupAuthoritiesByUsername(GROUPS_BY_USERNAME_QUERY);

    }


      @Override
    protected void configure(HttpSecurity http) throws Exception {


                // The http.formLogin().defaultSuccessUrl("/path/") method is required when using stateless Spring Security
        // because the session cannot be used to redirect to the page that was requested while signed out. Unfortunately
        // using this configuration method will cause our custom success handler (below) to be overridden with the
        // default success handler. So to replicate the defaultSuccessUrl("/path/") configuration we will instead
        // correctly configure and delegate to the default success handler.
        final SimpleUrlAuthenticationSuccessHandler delegate = new SimpleUrlAuthenticationSuccessHandler();
        delegate.setDefaultTargetUrl("/api/");
          // Make Spring Security stateless. This means no session will be created by Spring Security, nor will it use any
        // previously existing session.
        http.sessionManagement().sessionCreationPolicy(STATELESS);
        // Disable the CSRF prevention because it requires the session, which of course is not available in a
        // stateless application. It also greatly complicates the requirements for the sign in POST request.
        http.csrf().disable();
        // Viewing any page requires authentication.
        http.authorizeRequests().anyRequest().authenticated();
        http
          .formLogin().loginPage("http://localhost/web/ui/#access/signin")
          .permitAll()
            // Override the sign in success handler with our stateless implementation. This will update the response
            // with any headers and cookies that are required for subsequent authenticated requests.
            .successHandler(new NStatelessAuthenticationSuccessHandler(authenticationBinder, delegate));
        http.logout().logoutUrl("http://localhost/web/ui/#access/signin").logoutSuccessUrl("http://localhost/web/ui/#access/signin");
        // Add our stateless authentication filter before the default sign in filter. The default sign in filter is
        // still used for the initial sign in, but if a user is authenticated we need to acknowledge this before it is
        // reached.
        http.addFilterBefore(
            new StatelessAuthenticationFilter(authenticationBinder, securityContextHolder),
            UsernamePasswordAuthenticationFilter.class
        );

} 

}

我有两种类型的authenticationBinder,即基于令牌的和基于用户名的。

@Component
public class NXAuthTokenHttpServletRequestBinder implements NHttpServletRequestBinder<String> {

    private static final String X_AUTH_TOKEN = "X-AUTH-TOKEN";
    private final NTokenFactory tokenFactory;

    @Autowired
    public NXAuthTokenHttpServletRequestBinder(NTokenFactory tokenFactory) {
        this.tokenFactory = tokenFactory;
    }

    @Override
    public void add(HttpServletResponse response, String username) {

        final String token = tokenFactory.create(username);

        response.addHeader(X_AUTH_TOKEN, token);
        response.addCookie(new Cookie(X_AUTH_TOKEN, token));
    }

    @Override
    public String retrieve(HttpServletRequest request) {

        final String cookieToken = findToken(request);

        if (cookieToken != null) {
            return tokenFactory.parseUsername(cookieToken);
        }

        return null;
    }

    private static String findToken(HttpServletRequest request) {
        Enumeration<String> it = request.getHeaderNames();
        while(it.hasMoreElements()){
            System.out.println(it.nextElement());
        }
        final String headerToken = request.getHeader(X_AUTH_TOKEN);

        if (headerToken != null) {
            return headerToken;
        }

        final Cookie[] cookies = request.getCookies();

        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (X_AUTH_TOKEN.equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }

        return null;
    }
}
@Component
@Primary
public class NUserAuthenticationFactory implements NHttpServletRequestBinder<Authentication> {

    private final NHttpServletRequestBinder<String> httpServletRequestBinder;

    @Autowired

    public NUserAuthenticationFactory(NHttpServletRequestBinder<String> httpServletRequestBinder) {
        this.httpServletRequestBinder = httpServletRequestBinder;
    }

    @Override
    public void add(HttpServletResponse response, Authentication authentication) {
        httpServletRequestBinder.add(response, authentication.getName());
    }

    @Override
    public UserAuthentication retrieve(HttpServletRequest request) {

        final String username = httpServletRequestBinder.retrieve(request);

        if (username != null) {

            return new UserAuthentication(new CustomJDBCDaoImpl().loadUserByUsername(username));
        }

        return null;
    }
}

共有1个答案

哈宪
2023-03-14

逐步解决你的问题可以是…

>

  • 使用spring securityUsernamePasswordAuthenticationFilter通过用户名和密码对用户进行身份验证,并生成唯一令牌。
  • 编写另一个自定义安全筛选器和AuthenticationProvider实现,以对用户进行连续请求的身份验证。
  • 将自定义安全筛选器放置在UsernamePasswordAuthenticationFilter之前,如下所示

    http.AddFilterBefore(CustomTokenBasedAuthenticationFilter,UsernamePasswordAuthenticationFilter.Class);

  •  类似资料:
    • 我试图用RESTAPI实现Spring Security性,并作为前端进行响应,因为这是我的第一个完整堆栈开发项目,我对如何实现正确的身份验证机制一无所知。 我已经搜索了很多,找到了关于Spring Security with Basic Auth的文章,但我无法弄清楚如何将该身份验证转换为其他api,然后通过会话/cookie进行管理。即使我得到的任何github引用都很旧,或者它们还没有完全迁

    • 我正在学习springsecurity(基于java的配置),我无法使注销正常工作。当我点击注销时,我看到URL更改为http://localhost:8080/logout并获取“HTTP 404-/logout”。登录功能工作正常(即使使用自定义登录表单),但问题是注销,我怀疑重定向的url“localhost:8080/logout”应该类似于“localhost:8808/springte

    • 我使用已签名的URL从使用Air的移动设备上传blob。 我有两个问题: 使用签名 URL 上传 Blob 时,我假设我不需要按照文档中所述包含所有标头。我是否认为我只需要对URL执行请求,并将编码到正文中的文件包含在正文中,设置为? http://msdn . Microsoft . com/en-us/library/windows azure/DD 179451 . aspx (Upload

    • 主要内容:1.入门,2.设置用户名和密码1.入门 1.启动一个SpringBoot项目 2.导入SpringSecurity相关依赖 3.编写Controller TestController.java 用户是user 密码是刚刚的 2.设置用户名和密码 1.在配置文件中设置 2.在配置类中设置 3.自定义实现类 2.1 配置文件中设置 2.2 在配置类中设置 设置用户名为zZZ,密码为root 2.3 自定义实现类 配置类: 业务类:

    • 我有一个管理Web应用程序位于远程服务器上。这个应用程序是使用MEAN堆栈编写的,我有一个连接到网络应用程序所需的所有RESTful路由的列表。 我正在编写一个Java客户端应用程序,它需要从这个管理应用程序发送和接收数据。如果我有服务器的IP地址和REST路由,如何将客户端连接到web应用程序? 我想我需要提供一个到服务器和RESTAPI文件的URL连接,然后只需调用路由函数,如和。

    • 本文向大家介绍如何使用SpringSecurity保护程序安全,包括了如何使用SpringSecurity保护程序安全的使用技巧和注意事项,需要的朋友参考一下 首先,引入依赖: 引入此依赖之后,你的web程序将拥有以下功能: 所有请求路径都需要认证 不需要特定的角色和权限 没有登录页面,使用HTTP基本身份认证 只有一个用户,名称为user 配置SpringSecurity springsecur

    • 问题内容: 我目前正在评估基于Java的安全框架,我是Spring 3.0用户,因此似乎似乎SpringSecurity是正确的选择,但是Spring安全性似乎受到过分复杂的困扰,它似乎并没有使安全性易于实现, Shiro似乎更加连贯,更容易理解。我正在寻找这两个框架之间的利弊清单。 问题答案: 我也同意Spring Security对我来说感觉太复杂了。当然,他们已经做了一些降低复杂性的事情,例

    • 我能够使用CURL命令在JIRA中创建一个票证,并且手头有一个json数据。 curl-D--u:-X POST--data@ 我现在正试图更新生成的票证的状态,但出现以下错误<代码>{“errorMessages”:[],“errors”:{“status”:“无法设置字段‘status’。它不在适当的屏幕上,或未知。”} 卷曲命令: 旋度-D--u