Exemplo de autorização de acesso baseado em função de segurança do Spring
Hoje, examinaremos o exemplo de autorização e acesso baseado na função de segurança do Spring. No entanto, antes de ler este post, leia meu post anterior sobre \Exemplo de logout de login do Spring 4 Security MVC para obter algum conhecimento básico sobre o Spring 4 Security.
Função de segurança do Spring
Nesta postagem, discutiremos como definir, usar e gerenciar as funções de segurança do Spring como \USER, \ADMIN no Spring Web Application. Como meu post anterior, este exemplo de post também está usando Spring 4 MVC Security com In-Memory Store e Spring Java Configuration Feature para desenvolver o aplicativo. Isso significa que não vamos usar o arquivo web.xml e também não vamos escrever nem uma única linha de configuração Spring XML. Usaremos a opção \In-Memory Store para armazenar e gerenciar as credenciais do usuário. Usaremos Spring 4.0.2.RELEASE, Spring STS 3.7 Suite IDE, Spring TC Server 3.1 com Java 1.8 e ferramenta de compilação Maven para desenvolver isso exemplo.
Exemplo de autorização de acesso baseado em função de segurança do Spring
- Crie um projeto \Simple Spring Web Maven no Spring STS Suite com os seguintes detalhes. Nome do projeto: SpringMVCSecruityMavenRolesApp2. Use o mesmo arquivo pom.xml da minha postagem anterior com as seguintes alterações
<artifactId>SpringMVCSecruityMavenRolesApp</artifactId>
<build>
<finalName>SpringMVCSecruityMavenRolesApp</finalName>
</build>
</project>
- Use todos os arquivos Java e JSP do meu post anterior. Discutiremos apenas o conteúdo atualizado ou adicionado recentemente aqui.
- Atualize o arquivo LoginSecurityConfig.java para configurar funções de usuário como \USER e \ADMIN. LoginSecurityConfig.java
package com.journaldev.spring.secuity.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
authenticationMgr.inMemoryAuthentication()
.withUser("jduser").password("jdu@123").authorities("ROLE_USER")
.and()
.withUser("jdadmin").password("jda@123").authorities("ROLE_USER","ROLE_ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/homePage").access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
.antMatchers("/userPage").access("hasRole('ROLE_USER')")
.antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
}
Explicação do código
- No método configureGlobal(), adicionamos dois usuários: um usuário com a função \ROLE_USER e outro usuário com as funções \ROLE_USER e \ROLE_ADMIN. Isso significa que este segundo usuário atuará como um usuário administrador . Assim, podemos configurar qualquer número de usuários e funções.
- Podemos usar métodos de autoridades (ROLE) ou funções (ROLE) para configurar funções em nosso aplicativo.
- Diferença entre os métodos autoridades() e funções():
- authorities() precisa do nome completo da função como \ROLE_USER”
- roles() precisa de um nome de papel como \USER. Ele adicionará automaticamente o valor \ROLE_ a esse nome de papel \USER.
- No método configure(), definimos URLs diferentes com funções de acesso necessárias.
antMatchers("/homePage")
.access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
Este trecho de código configura que \/homePage está disponível para funções de USUÁRIO e ADMIN.
.antMatchers("/userPage").access("hasRole('ROLE_USER')")
.antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")
Este trecho de código configura que \/userPage é acessível apenas pela função \USER e .\/adminPage é acessível apenas pela função \ADMIN. Se outras funções acessarem essas páginas, obteremos a mensagem de erro \403 Acesso negado.
- Atualize o arquivo do controlador LoginController.java para definir novos caminhos de acesso à URL, conforme mostrado abaixo. LoginController.java
package com.journaldev.spring.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController {
@RequestMapping(value = { "/"}, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.setViewName("welcomePage");
return model;
}
@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
public ModelAndView homePage() {
ModelAndView model = new ModelAndView();
model.setViewName("homePage");
return model;
}
@RequestMapping(value = {"/userPage"}, method = RequestMethod.GET)
public ModelAndView userPage() {
ModelAndView model = new ModelAndView();
model.setViewName("userPage");
return model;
}
@RequestMapping(value = {"/adminPage"}, method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.setViewName("adminPage");
return model;
}
@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid Credentials provided.");
}
if (logout != null) {
model.addObject("message", "Logged out from JournalDEV successfully.");
}
model.setViewName("loginPage");
return model;
}
}
Explicação do código Além do exemplo do post anterior, aqui adicionamos mais duas novas URLs.
- \/userPage é usado pela função USER para acessar e executar atividades normais do usuário.
- \/adminPage é usado pela função ADMIN para acessar e executar atividades do usuário Admin. A função ADMIN pode acessar a URL \/userPage também.
- Arquivo homePage.jsp atualizado para fornecer atividades específicas de funções de usuário e administrador. homePage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<a href="${pageContext.request.contextPath}/userPage">JD User</a> | <a href="${pageContext.request.contextPath}/adminPage">JD Admin</a> | <a href="javascript:document.getElementById('logout').submit()">Logout</a>
<h3>Welcome to JournalDEV Tutorials</h3>
<ul>
<li>Java 8 tutorial</li>
<li>Spring tutorial</li>
<li>Gradle tutorial</li>
<li>BigData tutorial</li>
</ul>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
Aqui, adicionamos três opções de menu no quadro superior. \Logout já foi discutido em meu post anterior. Novos dois links são:
- Usuário JD: Acessível pelas funções \USER e \ADMIN
- JD Admin: Acessível apenas por ambas as funções \ADMIN
NOTA:- Em aplicações de tempo real, mostraremos apenas o link \JD User para a função \USER e ocultaremos o link \JD Admin. Para testar se é acessível pela função \USER ou não e também para ver a mensagem de erro exata, não ocultamos este link.20. Inclua o novo arquivo adminPage.jsp para atuar como uma página inicial para a função \ADMIN.
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>Admin Page</h3>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>
- Adicione o novo arquivo userPage.jsp para atuar como uma página inicial para a função \USER. userPage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>User Page</h3>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>
Concluímos o desenvolvimento de nosso aplicativo agora. É hora de ver a estrutura final do nosso projeto e testar a aplicação.26. A estrutura final do projeto fica assim:
Teste de aplicativo de exemplo de funções de segurança do Spring
Isso é tudo sobre o exemplo de funções de segurança do Spring para fornecer acesso autorizado a páginas de aplicativos da web.