Spring Security Java Spring Web安全

ttcibm8c  于 2023-11-19  发布在  Spring
关注(0)|答案(1)|浏览(146)

我试图写一个API接口,传入的HTTP请求必须根据数据库中的用户名和密码进行身份验证。这是一种情况,其中2台服务器需要与第三方服务器验证请求,看看它是否有效。场景是这样的:
1.请求服务器通过HTTP POST发送用户会话ID。
1.我的应用程序将会话ID发送到另一个返回用户名的第三方服务器。
1.我的应用程序根据我的数据库检查用户名,并手动设置会话令牌。
1.对我的API的后续请求将需要使用基本身份验证的POST头中的用户名和密码。
我有SecurityConfig:

@EnableWebSecurity
class SecurityConfig {
   @Bean
   public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
   }
   @Configuration
   @Order(1)
   public class MyAPISecurityConfig extends WebSecurityConfigurerAdapter {

        @Bean
        public MyUserDetailsService myUserDetailsService() {
            return new MyUserDetailsService();
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.eraseCredentials(false)
                    .userDetailsService(myUserDetailsService())
                    .passwordEncoder(passwordEncoder());
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            List<String> PATHS_WEB_PERMIT_ALL = new ArrayList<String>();
            PATHS_WEB_PERMIT_ALL.add("/rest/myApi/verifyUser");
            http.authorizeRequests()
                .antMatchers(StringUtils.toStringArray(PATHS_WEB_PERMIT_ALL)).permitAll()
                .antMatchers("/rest/myApi/**").authenticated()
                .and()
                .httpBasic();
            http.sessionManagement().maximumSessions(1);
            http.csrf().disable();
        }
    }
}

字符串
我的userDetailsService:

public class MyUserDetailsService implements UserDetailsService {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyUserDetailsService.class);

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LOGGER.info("Finding user: {}", username);
        CommUser commUser = commUserService.findByUsernameWithRoles(username);
        if (commUser == null) {
            LOGGER.error("Unable to find user by username!" + username);
            throw new UsernameNotFoundException("User not found!");
        } else {
            commUser.setAuthorities(createAuthorities(commUser));
            return commUser;
        }
    }

    private Set<GrantedAuthority> createAuthorities(CommUser commUser) {
        Set<GrantedAuthority> authorities = new LinkedHashSet<>();
        List<CommRoleFunctionMode> commRoleFunctionModes = roleFunctionModeRepository.findByCommRoleIn(commUser.getCommRoles());
        for (CommRoleFunctionMode commRoleFunctionMode : commRoleFunctionModes) {
            authorities.add(new SimpleGrantedAuthority(commRoleFunctionMode.getCommFunction().getFunctionName()));
            authorities.add(new SimpleGrantedAuthority(commRoleFunctionMode.getCommFunction().getFunctionName() + commRoleFunctionMode.getCommMode().getModeName()));
        }
        return authorities;
    }

    @Autowired
    private CommUserService commUserService;

    @Autowired
    private CommRoleFunctionModeRepository roleFunctionModeRepository;


我的RestController:

@RestController
@RequestMapping("/rest/myApi/")
public class MyApiController {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyApiController.class);

    @PostMapping("verifyUser")
    public ResponseEntity verifyUser(@RequestBody @Valid UserKeyDto userKeyDto, HttpServletRequest httpRequest, ProviderManager  providerManager) {
        if (myApiRestService.myApiLoginValidate(userKeyDto, httpRequest, providerManager)) {
            return new ResponseEntity(HttpStatus.OK);
        } else {
            return new ResponseEntity<>("The username is incorrect!", HttpStatus.UNAUTHORIZED);
        }
    }

    @Autowired
    private MyApiRestService myApiRestService;
}


和我的MyApiRestService(这是大部分验证发生的地方):

@Service
@CacheConfig(cacheNames = {"myApiRestService"})
public class MyApiRestService {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyApiRestService.class);
    
    @Transactional
    public boolean myApiLoginValidate(UserKeyDto userKeyDto, HttpServletRequest httpRequest, ProviderManager providerManager) {
        String verifyUserUrl = environment.getProperty("api.url") + "/verifyUser";
        
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> request = new HttpEntity<String>(userKeyDto.getSessionId(), headers);
        
        UserKeyDto returnedUserKeyDto = restTemplate.postForObject(verifyUserUrl, request, UserKeyDto.class);
        
        UserDetails userDetails = myUserDetailsService.loadUserByUsername(returnedUserKeyDto.getUsername());
          
        if(userDetails==null) {
            return Boolean.FALSE;
        }
        
        HttpSession session = httpRequest.getSession(false);
        if (session == null) {
            session = httpRequest.getSession();   
        }
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails.getUsername(),
                userDetails.getPassword(), userDetails.getAuthorities());

        token.setDetails(new WebAuthenticationDetails(httpRequest));
        Authentication authenticatedUser = providerManager.authenticate(token);

        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
        // setting role to the session
        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
                SecurityContextHolder.getContext());    
        
        return Boolean.TRUE;
    }

    @Autowired
    Environment environment;
    @Autowired
    MyUserDetailsService myUserDetailsService;


UserKeyDto:

public class UserKeyDto  {
    private static final long serialVersionUID = -2440534315863428792L;
    
    @NotEmpty(message = "SessionId is required!")
    private String sessionId;
    
    private String username;
}


HTTP请求时出错:
找不到默认的构造函数;嵌套的异常是java. lang. NoSuchMethodException:找不到默认的构造函数;嵌套的构造函数是java.lang.NoSuchMethodException:找不到默认的构造函数;嵌套的构造函数是java. lang.NoSuchMethodException:找不到默认的构造函数。
Controller似乎无法示例化ProviderManager。请帮助。谢谢。

kgsdhlau

kgsdhlau1#

我可以建议一个可能的解决方案,但我不确定:从MyApiController中的控制器方法中删除ProviderManager参数:

@PostMapping("verifyUser")
public ResponseEntity verifyUser(@RequestBody @Valid UserKeyDto userKeyDto, HttpServletRequest httpRequest) {
    if (myApiRestService.myApiLoginValidate(userKeyDto, httpRequest)) {
        return new ResponseEntity(HttpStatus.OK);
    } else {
        return new ResponseEntity<>("The username is incorrect!", HttpStatus.UNAUTHORIZED);
    }
}

字符串
在SecurityConfig类中配置ProviderManager:

@Bean
public ProviderManager providerManager(List<AuthenticationProvider> providers) {
    return new ProviderManager(providers);
}

相关问题