Exemplo de Autorização de Acesso Baseada em Função do Spring Security

Hoje vamos analisar um exemplo de acesso e autorização baseados em funções de segurança da primavera. No entanto, antes de ler este post, por favor, dê uma olhada no meu post anterior sobre “Exemplo de Login e Logout do Spring 4 Security MVC” para obter algum conhecimento básico sobre o Spring 4 Security.

Função de Segurança da Primavera

Neste post, discutiremos como definir, usar e gerenciar funções de segurança da primavera, como “USUÁRIO” e “ADMINISTRADOR” em uma aplicação web da primavera. Assim como no meu post anterior, este exemplo também está usando o Spring 4 MVC Security com o Armazenamento em Memória e o Recurso de Configuração Java da Primavera para desenvolver a aplicação. Isso significa que não vamos usar o arquivo web.xml e também não escreveremos nem uma única linha de Configuração XML da Primavera. Vamos usar a opção “Armazenamento em Memória” para armazenar e gerenciar as Credenciais do Usuário. Vamos usar o Spring 4.0.2.RELEASE, Spring STS 3.7 Suite IDE, Spring TC Server 3.1 com Java 1.8 e a ferramenta de compilação Maven para desenvolver este exemplo.

Exemplo de Autorização de Acesso Baseado em Funções da Primavera Security

  1. Crie um projeto “Simple Spring Web Maven” no Spring STS Suite com os seguintes detalhes.
    Nome do Projeto: SpringMVCSecurityMavenRolesApp2. Utilize o mesmo arquivo pom.xml do meu post anterior com as seguintes alterações
<artifactId>SpringMVCSecruityMavenRolesApp</artifactId>

<build>
  <finalName>SpringMVCSecruityMavenRolesApp</finalName>
</build>
</project>
  1. Use todos os arquivos Java e JSP do meu post anterior. Discutiremos apenas o conteúdo atualizado ou recém-adicionado aqui.
  2. 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

  1. 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. Podemos configurar qualquer número de usuários e funções desta forma.
  2. Podemos usar os métodos authorities(ROLE) ou roles(ROLE) para configurar funções em nossa aplicação.
  3. Diferença entre os métodos authorities() e roles():
  • authorities() precisa do nome completo da função, como “ROLE_USER”
  • roles() precisa do nome da função, como “USER”. Ele adicionará automaticamente o valor “ROLE_” a este nome de função “USER”.
  1. No método configure(), definimos diferentes URLs 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 as funções USER 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, receberemos a mensagem de erro “403 Access is Denied”.

  1. Atualize o arquivo de controle 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 anterior, aqui adicionamos mais dois novos URLs.

  1. “/userPage” é usado pela função USUÁRIO para acessar e realizar atividades de usuário normal.

  2. “/adminPage” é usado pela função ADMIN para acessar e realizar atividades de usuário administrador. A função ADMIN também pode acessar o URL “/userPage”.

  3. Atualizado o arquivo homePage.jsp para fornecer atividades específicas para as 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 topo. “Logout” já foi discutido em minha postagem anterior. Os dois novos links são:

  1. JD Usuário: Acessível tanto pelas funções “USUÁRIO” quanto “ADMIN”
  2. JD Administrador: Acessível apenas pela função “ADMIN”

NOTA:- Em aplicações em tempo real, mostraremos apenas o link “JD Usuário” para a função “USUÁRIO” e ocultaremos o link “JD Administrador”. Para testar se é acessível pela função “USUÁRIO” ou não e também para ver a mensagem de erro exata, não ocultamos este link.20. Adicione um novo arquivo adminPage.jsp para atuar como uma página inicial para a função “ADMIN”. adminPage.jsp

<%@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>
  1. Adicione um novo arquivo userPage.jsp para servir como Página Inicial para o papel de “USUÁRIO”.
    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>

Nós concluímos o desenvolvimento de nossa aplicação agora. É hora de ver a estrutura final do nosso projeto e testar a aplicação.26. A Estrutura Final do Projeto se parece com isso:

Teste de Exemplo de Aplicativo de Funções de Segurança do Spring

  1. Clique com o botão direito no projeto no IDE Spring STS e selecione a opção “Executar como >> Executar no Servidor”. Isso acessará a página de boas-vindas do aplicativo padrão conforme mostrado abaixo: 3. Clique no link “Login no JournalDEV”. Agora você está na página de login. 5. Faça o login pela primeira vez com as credenciais do “USER”: Nome de usuário: jduser Senha: jdu@123 Agora veremos a página inicial do aplicativo com 3 opções de menu: “JD User”, “JD Admin” e “Logout”. Clique no link “JD User”. Como fizemos login no aplicativo usando as credenciais do “USER”, podemos acessar este link conforme mostrado abaixo. Basta usar a seta para trás no IDE Spring STS e desta vez clicar no link “JD Admin”. Como fizemos login com as credenciais do “USER”, não podemos acessar este link. Por isso vimos esta mensagem de erro: “403 Acesso negado”.9. Agora faça logout e faça login novamente com as credenciais do “ADMIN”: Nome de usuário: jdadmin Senha: jda@123 Desta vez podemos acessar com sucesso o link “JD Admin” conforme mostrado abaixo. Teste o link “Logout” para sair do aplicativo.

Isso é tudo sobre o exemplo de papéis de segurança do Spring para fornecer acesso autorizado às páginas da aplicação web.

Source:
https://www.digitalocean.com/community/tutorials/spring-security-role-based-access-authorization-example