Introdução básica de segurança da primavera
Não vou dar muita introdução à segurança da primavera aqui. Para detalhes, consulte a documentação oficial.
Só falarei sobre as funções principais do SpringSecurity:
Construção básica do ambiente
Aqui usamos o Springboot como a estrutura básica do projeto. Estou usando o método MAVEN para gerenciamento de pacotes, então aqui fornecemos o método para integrar a segurança da primavera.
<Dependences> ... <Ependency> <PuerpId> org.springframework.boot </groupiD> <TRATIFACTID> Spring-boot-Starter-Security </ArtifactId> </Dependency> ... </Dependências>
Em seguida, estabeleça uma interface de solicitação de camada da web
@RestController @requestmapp ("/user") classe pública UserController {@GetMapping public String getUsers () {return "Hello Spring Security"; }}Em seguida, você pode executar o projeto diretamente e chamar a interface para ver o efeito.
Chamando através da página da web
Primeiro, fazemos a interface chamada através do navegador e acessamos diretamente http: // localhost: 8080/usuário. Se a interface puder ser acessada normalmente, "Hello Spring Security" deve ser exibido.
Mas não podemos acessá -lo normalmente, e a caixa de entrada de autenticação na figura abaixo aparece
Isso ocorre porque no trampolim, a segurança padrão da primavera é eficaz. Neste momento, as interfaces estão protegidas e precisamos passar a verificação para acessá -las normalmente. A Spring Security fornece um usuário padrão, o nome do usuário é o usuário e a senha é gerada automaticamente quando o projeto é iniciado.
Quando verificarmos o log de inicialização do projeto, encontraremos o seguinte log
Usando a senha de segurança padrão: 62CCF9CA-9FBE-4993-8566-8468CC33C28C
Obviamente, a senha que você vê deve ser diferente da minha. Fazemos login diretamente com o usuário e a senha no log de inicialização.
Depois de fazer login com sucesso, você pula para a página em que a interface é chamada normalmente.
Se você não deseja ativar a segurança da primavera desde o início, pode configurar o seguinte no arquivo de configuração:
# Segurança Ativar segurança.basic.enabled = false
A caixa de login que acabei de ver foi fornecida pelo SpringSecurity, que é chamada httpbasiclogin. Não é o que queremos em nosso produto. Nosso front-end geralmente executa a verificação de login de usuários por meio de envio de formulário, por isso precisamos personalizar nossa própria lógica de autenticação.
Personalize a lógica de autenticação do usuário
Cada sistema deve ter seu próprio conjunto de sistemas de usuário, por isso precisamos personalizar nossa própria lógica de autenticação e interface de login.
Aqui precisamos configurar o SpringSecurity de acordo
@ConfigurationPublic Class BrowerSecurityConfig estende WebSecurityConfigureRAdApter {@Override Protected void Configure (httpsecurity http) lança exceção {http.formLogin () // define a página de login a ser transferida quando o usuário é necessário para Log em. protegido e que não precisam ser protegidos. }}Em seguida, configure a lógica de autenticação do usuário, porque temos nosso próprio sistema de usuário.
@ComPonenPublic Classe myUserDetailSService implementa UserDetailSService {private Logger Logger = LoggerFactory.getLogger (getClass ()); @Override public userDetails loadUserByUserName (String UserName) lança UserNameNotFoundException {Logger.info ("Nome de usuário do usuário: {}", nome de usuário); // TODO De acordo com o nome de usuário, encontre a senha correspondente e encapsule as informações do usuário e retorne. Os parâmetros são: Nome do usuário, senha, permissões do usuário Usuário do usuário = novo Usuário (UserMame, "123456", AuthorityUtils.CommaseParatedStringToAuthorityList ("Admin")); devolver usuário; }} Não realizamos muita verificação aqui. O nome de usuário pode ser preenchido à vontade, mas a senha deve ser "123456" para que possamos fazer login com sucesso.
Ao mesmo tempo, podemos ver que o terceiro parâmetro do objeto do usuário aqui representa as permissões do usuário atual e o definimos como "admin".
Execute o programa para testá -lo e você descobrirá que a interface de login mudou.
Isso ocorre porque configuramos http.formLogin() no arquivo de configuração
Vamos preencher um usuário aqui e, em seguida, preencher uma versão errada (não-123456). Isso levará a um erro de verificação:
Ao mesmo tempo, no console, o usuário que você acabou de preencher quando fizer login também será impresso.
Agora, vamos tentar fazer login com a senha correta. Você pode descobrir que ele passará a verificação e pulará para a página de chamada de interface correta.
UserDetails
Agora, quando estávamos escrevendo MyUserDetailsService , implementamos um método e retornamos um UserDetails . Este userDetails é um objeto que encapsula as informações do usuário, que contém sete métodos
interface pública UserDetails estende serializável {// Coleção de informações de permissão encapsulada <? estende a concessão de autoridade> getAuthorities (); // informações de senha string getPassword (); // Login nome de usuário string getUserName (); // se a conta expira o booleano isaccoundnonexirired (); // se a conta é congelada booleana isaccoundNonlocked (); // Se a senha da conta expira, geralmente alguns sistemas com requisitos de senha altos o usarão. Comparado com o usuário, é necessário redefinir a senha de vez em quando boolean iscredentialsnonexirird (); // A conta está disponível? boolean isenabled ();}Quando retornarmos o usuário da classe de implementação do userDetails, podemos definir os parâmetros correspondentes através do método do construtor do usuário
Criptografia e descriptografia de senha
Existe uma interface de senha do SpringSecurity
interface pública PasswordEncoder {// criptografar o codificador de string de senha (Charsequence var1); // Determine a senha para corresponder a correspondências booleanas (Charsequence Var1, String var2);} Só precisamos implementar essa interface e configurá -la no arquivo de configuração.
Aqui vou testá -lo temporariamente com uma classe de implementação fornecida por padrão
// BrowerSecurityConfig @BeanPublic PasswordEncoder PasswordEncoder () {return New BCryptPasswordEncoder (); }Uso de criptografia:
@ComPonenPublic Classe myUserDetailSService implementa UserDetailSService {private Logger Logger = LoggerFactory.getLogger (getClass ()); @AUTOWIRED PRATDERENCODER PRAVADA DE PRAVADA; @Override public userDetails loadUserByUserName (String UserName) lança UserNameNotFoundException {Logger.info ("Nome de usuário do usuário: {}", nome de usuário); String senha = senha -coder.encode ("123456"); logger.info ("senha: {}", senha); // Os parâmetros são: Nome do usuário, senha, usuário do usuário Usuário do usuário = novo usuário (nome de usuário, senha, AuthorityUtils.ComMaseParatedStringToaAthorityList ("Admin")); devolver usuário; }}Aqui, simplesmente criptografamos 123456. Podemos realizar testes e descobrir que a senha impressa cada vez é diferente. Este é o papel do BCRYPTPASSPRATENCODER configurado.
Lógica de autenticação de usuário personalizada
Página de login personalizada
Nos testes anteriores, a interface de login padrão sempre foi usada. Acredito que cada produto possui seu próprio design de interface de login; portanto, aprenderemos sobre como personalizar a página de login nesta seção.
Vamos escrever uma página de login simples primeiro
<! Doctype html> <html lang = "pt"> <head> <meta charset = "utf-8"> <title> página de login </title> </ad head> <body> <h2> página de login personalizado </h2> <form ação = "/user/login" = "post"> <table> <tr> type = "text" name = "nome de usuário"> </td> </tr> <tr> <td> senha: </td> <td> <input type = "senha" name = "senha"> </td> </tr> <tr> <td colspan = "2"> <butt = "submit"> login </botão </td </morm> </body> </html>
Depois de concluir a página de login, você precisa configurá -lo para a SpringSecurity
// BrowerSecurityconfig.java@overrideProtected Void Configure (httpsecurity http) lança exceção {http.formLogin () // define a página de login a ser transferida para quando o usuário precisar fazer login. Page.LoginProcessingUrl ("/user/login") // interface de login personalizado.and () .authorizerequests () // Definir quais URLs precisam ser protegidos e que não precisam ser protegidos.antmatchers ("/login.html"). .authenticated () .and () .csrf (). desabille (); // Desative a proteção do CSRF}Dessa forma, sempre que acessamos a interface protegida, seremos transferidos para a página Login.html
Lidar com diferentes tipos de solicitações
Porque agora, as extremidades dianteiras e traseiras geralmente são separadas, o back -end fornece interfaces para que a front end e retorne os dados do formato JSON para o front end. Como antes, a interface protegida foi chamada e o salto da página foi redirecionado diretamente. É aceitável no lado da web, mas não é possível no lado do aplicativo, por isso precisamos fazer um processamento adicional.
Aqui está uma ideia simples de resolver
Primeiro, escreva um controlador personalizado e pule para ele quando a autenticação de identidade for necessária.
@RestControllerPublic Class BrowSerSecurityController {private Logger Logger = LoggerFactory.getLogger (getClass ()); // armazenamento em cache e recuperação de informações de solicitação original Private RequestCache RequestCache = new HttpSessionRequestCache (); // usado para redirecionar RedirectStrateg de redirecção privada RedirectStrategy = new DeFaultrredirectStrategy (); /** * Quando a autenticação da identidade é necessária, pule * @param request * @param resposta * @return */@requestMapping ("/autenticação/requer") @Responsestatus (code = HTTPStSatus.UnAuthorized) Public BaserSponse requer resposta (HSOSTRETRETRE -SAVE -SEDOR, HTTE -SERTE -SEDOR, HTERE -SEDORTESTPERSEPROPTENSTEMPERSEVERSEVERSEVERSEVERSE -SERTE -SAVE -SEDOR, HTERE -SERTE -SEDORE, savedRequest = requestcache.getRequest (solicitação, resposta); if (savedRequest! = null) {string TargetUrl = savedRequest.getRedirectURL (); Logger.info ("A solicitação para acionar um salto é:" + Targeturl); if (stringUtils.endswithignorecase (TargetUrl, ".html")) {RedirectStrategy.sendRedirect (solicitação, resposta, "/Login.html"); }} Retorne o novo BaseSponse ("O serviço acessado requer autenticação de identidade, orie o usuário para a página de login"); }}Obviamente, o arquivo de configuração precisa ser modificado de acordo, para que não publique o código aqui. É para abrir a interface.
Extensões:
Aqui, escrevemos a interface que é acessada a partir de uma página da web e, em seguida, pule para a página "/login.html". De fato, podemos expandi -lo e configurar o endereço de salto para o arquivo de configuração, que será mais conveniente.
Login de processamento personalizado bem -sucedido/falhado
Nos testes anteriores, o redirecionamento da página foi realizado após o login bem -sucedido.
No caso de separação das extremidades dianteiras e traseiras, se efetuarmos login com sucesso, talvez seja necessário retornar as informações pessoais do usuário ao front -end, em vez de pular diretamente. O mesmo vale para o login com falha.
Isso envolve duas interfaces no Spring Security AuthenticationSuccessHandler e AuthenticationFailureHandler . Podemos implementar essa interface e configurá -la de acordo. Obviamente, a estrutura possui uma classe de implementação padrão. Podemos herdar esta classe de implementação e personalizar nossos negócios
@ComPonent ("MyAuthenctiationSuccessHandler") Classe pública MyAuthenctiationSuccessHandler estende SimpleRlauthenticationsUccessHandler {private logger Logger = LoggerFactory.getLogger (getClass ()); @Autowired Private ObjectMapper ObjectMapper; @Override public void onAuthenticationsuccess (solicitação httpServletRequest, resposta httpSertLeSponse, autenticação de autenticação) lança ioexception, servletexception {logger.info ("login bem -sucedido"); Response.setContentType ("Application/json; charset = utf-8"); Response.getWriter (). Write (objectMapper.WriteValuEasString (Autenticação)); }} Aqui retornamos uma string json através da resposta.
O terceiro parâmetro neste método, Authentication , contém as informações do usuário de login (userDetails), informações de sessão, informações de login etc.
@Component ("MyAuthenctiationFailureHandler") Public Class MyAuthenctiationFailureHandler estende SimpleUrlaThenticationFailureHandler {private logger Logger = LoggerFactory.getLogger (getClass ()); @Autowired Private ObjectMapper ObjectMapper; @Override public void onAuthenticationFailure (solicitação httpServletRequest, resposta httpSertLeSponse, exceção de autenticaçãoException) lança ioexception, servletexception {logger.info ("login falhou"); Response.SetStatus (httpstatus.internal_server_error.value ()); Response.setContentType ("Application/json; charset = utf-8"); Response.getWriter (). Write (objectMapper.WriteValuEasString (New BaseSponse (excepcion.getMessage ()))); }} O terceiro parâmetro neste método AuthenticationException , inclui informações sobre a falha de login.
Da mesma forma, ainda é necessário configurá -lo no arquivo de configuração. Não vou postar todo o código aqui, apenas as instruções correspondentes são publicadas.
.successHandler (myauthenticationsuccesshandler) // Login personalizado lida com sucesso.FailureHandler (MyAuthenticationFailureHandler) // Falha de login personalizada Handles
Código
Você pode clicar em mim para ver o código completo
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.