Spring rest 配置jwt 安全驗證

在用spring + mybatis 作項目。以前安全驗證用basic 方式如今想換成jwt。java

jwt :web

JWS模式對這個內容進行了數字化簽名。這個內容被用來存放JWT的聲明.服務端簽名出JWT而且發送到客戶端,並在用戶成功認證後進行應答。服務器指望客戶端在下次請求的時候將JWS做爲請求的一部分,發送回服務端。算法

  若是咱們處理的客戶端是欺騙者則麼辦?這就是簽名(signature)須要出場的地方了。簽名攜帶了完整的可驗證的信息。換句話說,服務器能夠確認,接收到的JWT聲明裏的JWS是沒有通過欺騙客戶端、中間者進行修改的。spring

  服務端經過驗證消息的簽名來確保客戶端沒有修改聲明。若是服務端檢測到任何修改,能夠採起適當的動做(拒絕此次請求或者鎖定客戶端之類的)api

  客戶端一樣能夠驗證簽名,爲了作到這點,客戶端也須要服務端的secret(密鑰)(若是這個JWT簽名是HMAC算法),或者須要服務端對公鑰(若是這個WJT是數字化簽名)安全

  特別注意:對於JWS,荷載(聲明部分)沒有進行加密,因此,不要發送任何敏感信息.服務器

 

 

首先在web.xml 中session

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-mybatis.xml
			/WEB-INF/spring-security.xml
			classpath:applicationContext.xml
		</param-value>
	</context-param>



	<!-- Security -->
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>


	<servlet>
		<servlet-name>fly.fky</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>fly.fky</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

 

spring-sucurity.xmlmybatis

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
	<context:annotation-config />
	<global-method-security pre-post-annotations="enabled" />
	<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
		<beans:constructor-arg value="ThisIsASecretSoChangeMe" />
	</beans:bean>
	<!-- 
	<authentication-manager id="authenticationManager"
		erase-credentials="false">
		<authentication-provider user-service-ref="userService">
			<password-encoder ref="passwordEncoder"></password-encoder>
		</authentication-provider>
	</authentication-manager>
	<http pattern="/**" entry-point-ref="unauthorizedEntryPoint"
		create-session="stateless">
		<csrf disabled="true" />
		<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter" />
	</http>


	<beans:bean id="jwtAuthenticationFilter"
		class="fly.fky.restapi.security.JwtAuthenticationFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
		<beans:property name="authenticationSuccessHandler"
			ref="jwtAuthenticationSuccessHandler" />
	</beans:bean>

	<beans:bean id="unauthorizedEntryPoint"
		class="fly.fky.restapi.service.UnauthorizedEntryPoint" />


	<beans:bean id="jwtAuthenticationSuccessHandler"
		class="fly.fky.restapi.security.JwtAuthenticationSuccessHandler" />


	<!-- authentication manager -->

	<authentication-manager id="authenticationManager">
		<authentication-provider ref="jwtAuthenticationProvider">
		</authentication-provider>
	</authentication-manager>

	<beans:bean id="jwtAuthenticationProvider"
		class="fly.fky.restapi.security.JwtAuthenticationProvider" />
</beans:beans>

 

jwt filter 文件app

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	public JwtAuthenticationFilter() {
		super("/**");
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		String header = request.getHeader("Authorization");

        if (header == null || !header.startsWith("Bearer ")) {
        	throw new RestAPIAuthenticationException(MessageToClientFormat.formateMsg("No JWT token found in request headers"));
        }

        String authToken = header.substring(7);

       return JwtTokenUtil.getAuthentication(authToken);
	}

}

JwtAuthenticationProvider

public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

	@Resource
	private UserService userService;
	
	
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
		
		if (authentication.getCredentials() == null) {
			logger.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
		
		String presentedPassword = authentication.getCredentials().toString();

		if (!userService.isPasswordMatched(presentedPassword, userDetails.getPassword())) {
			logger.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
	}

	@Override
	protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		return userService.loadUserByUsername(username);
		
	}

}
相關文章
相關標籤/搜索