Recently learning the Spring security framework, learning to use the security framework to complete the system's secure channel control, to go back and forth encountered a lot of problems. Spring tutorial on the slightly simple, for me, such as small white is not enough to support the reading code, fortunately there is information on the network can be queried, in absorbing the experience of others, and then combined with their own debugging, the final realization of the desired effect. Next, I'll take a step-by-step process to restore this implementation, and look down.
One, about the installation of Tomcat certificate, SSL monitoring port implementation description
using Tomcat to enable SSL, you need to add the listening settings for SSL requests in the Server.xml file. There are a variety of ways, here to provide one, not the focus, do not repeat.
1. Use the JDK's Keytool tool to generate a server-side certificate
Keytool-genkeypair-alias tomcat-keyalg rsa-keypass 123456-storepass 123456-keystore E:/tomcat.keystore
2. Configuring Server.xml for SSL Monitoring
<ConnectorProtocol= "Org.apache.coyote.http11.Http11NioProtocol"Port= "8443"minsparethreads= "5"maxsparethreads= " the"enablelookups= "true"Disableuploadtimeout= "true"Acceptcount= "+"MaxThreads= "$"Scheme= "https"Secure= "true"sslenabled= "true"ClientAuth= "false"Sslprotocol= "TLS"Keystorefile= "E:/tomcat.keystore"Keystorepass= "123456"/>
3. (optionally) Configure Web. XML directly to complete the interception of the secure channel. This approach does not require the Spring security framework.
<Login-config> <Auth-method>Client-cert</Auth-method> <Realm-name>Client Cert users-only Area</Realm-name> </Login-config> <Security-constraint> <web-resource-collection> <Web-resource-name>Ssl</Web-resource-name> <Url-pattern>/*</Url-pattern> </web-resource-collection> <User-data-constraint> <Transport-guarantee>Confidential</Transport-guarantee> </User-data-constraint> </Security-constraint> </Web-app>
Second, verify the spring Security channel settings implementation instructions
1. Refer to the Spring tutorial instructions to complete the first HTTPS-enabled attempt. Open a secure connection to the/free/** request.
- My setup code ( . and (). Requireschannel (). Antmatchers("/free/**"). Requiressecure ())
@Configuration @enablewebsecurity Public classSecurityconfigextendsWebsecurityconfigureradapter {/*** HTTP request processing*/@Overrideprotected voidConfigure (Httpsecurity http)throwsException {http. Formlogin (). LoginPage ("/user/login.do"). Defaultsuccessurl ("/free/list.do")//Enable form Login. and (). Authorizerequests (). Antmatchers ("/user/login.do"). Permitall ()//The login page allows all people to access. and (). Authorizerequests (). Antmatchers ("/**/*.do"). Authenticated (). and (). Requireschannel (). Antmatchers ( "/free/**"). Requiressecure ()//. Channelprocessors (Getchannelprocessors ()). and (). CSRF (). disable ();//temporarily disable CSRF}
- Test it for a moment. reported a bunch of filter execution errors, and changed the requested path, more than one level ApplicationContext.
- Follow the source code to see the cause of the error. The stack call process is not detailed here, just to say the root of the problem.
1, the debug discovery needs to initiate secure access to the request will go into this method, assemble the redirect address. The Redirectport should return an HTTPS request listening port, but unfortunately this value is null.
2, Next I looked at Getmappedport this method, found spring security by default is built into two sets of corresponding mapping port (80->443,8080->8443). It's a good idea to make a mistake here, I test tomcat, set the HTTP request listening port is 8898, can not find the corresponding HTTPS port. Knowing the problem, let's start the rectification.
2, personal source code analysis, violence to specify their own channel request processing, set channelprocessors.
/*** HTTP request processing*/@Overrideprotected voidConfigure (Httpsecurity http)throwsException {http. Formlogin (). LoginPage ("/user/login.do"). Defaultsuccessurl ("/free/list.do")//Enable form Login. and (). Authorizerequests (). Antmatchers ("/user/login.do"). Permitall ()//The login page allows all people to access. and (). Authorizerequests (). Antmatchers ("/**/*.do"). Authenticated (). and (). Requireschannel (). Channelprocessors (Getchannelprocessors ()) . Antmatchers ("/free/**"). Requiressecure (). and (). CSRF (). disable (); //temporarily disable CSRF } /*** Set your own channel processor *@return */ PrivateList<channelprocessor>getchannelprocessors () {List<ChannelProcessor> list =NewArraylist<channelprocessor>(); Securechannelprocessor Processor=Newsecurechannelprocessor (); Retrywithhttpsentrypoint entrypoint=( (Retrywithhttpsentrypoint) processor.getentrypoint ()); //Redefining Port MappingsPortmapperimpl portmapper =NewPortmapperimpl (); HashMap<String,String> Maper =NewHashmap<string,string>(); Maper.put ("80", "443"); Maper.put ("8080", "8443"); Maper.put ("8898", "8443"); Portmapper.setportmappings (Maper); Entrypoint.setportmapper (portmapper); List.add (processor); List.add (Newinsecurechannelprocessor ()); returnlist; }
- Test it and see the results. As expected, it's ready!
3., look back, the framework is not so bad, right? Not a port mapping, you have to analyze a bunch of source code to know how to play? Could it be that I couldn't find my own way? The answer is yes, actually the framework has really provided a way to configure port mapping. Next is the elegant 3rd version of the implementation, please look down.
@Configuration @enablewebsecurity Public classSecurityconfigextendsWebsecurityconfigureradapter {/*** HTTP request processing*/@Overrideprotected voidConfigure (Httpsecurity http)throwsException {http. Formlogin (). LoginPage ("/user/login.do"). Defaultsuccessurl ("/free/list.do")//Enable form Login. and (). Authorizerequests (). Antmatchers ("/user/login.do"). Permitall ()//The login page allows all people to access. and (). Portmapper (). HTTP (8898). Mapsto (8443)//Add port mappings for testing. and (). Authorizerequests (). Antmatchers ("/**/*.do"). Authenticated (). and (). Requireschannel (). Antmatchers ( "/free/**" ). Requiressecure (). and (). Requireschannel (). Anyrequest (). Requiresinsecure (). and (). Httpbasic () . and (). CSRF (). disable (); //temporarily disable CSRF}
- Test it and see the results. Very good, this is the right way!
4, tried a few jump, found the click to exit the System button, back to the login page also became HTTPS request, does not meet the settings I want to effect ah. Judging by the results of this test, guess the whole process should be like this. After we have successfully entered an HTTPS request, the subsequent request is all pointing to port 8443 because it is a specified relative path. A display setting is required to allow other requests to be processed by the HTTP schema. Next is my 4th version of the implementation, please look down.
@Configuration @enablewebsecurity Public classSecurityconfigextendsWebsecurityconfigureradapter {/*** HTTP request processing*/@Overrideprotected voidConfigure (Httpsecurity http)throwsException {http. Formlogin (). LoginPage ("/user/login.do"). Defaultsuccessurl ("/free/list.do")//Enable form Login. and (). Authorizerequests (). Antmatchers ("/user/login.do"). Permitall ()//The login page allows all people to access. and (). Portmapper (). HTTP (8898). Mapsto (8443)//Add port mappings for testing. and (). Authorizerequests (). Antmatchers ("/**/*.do"). Authenticated (). and (). Requireschannel (). Antmatchers ( "/free/**" ). Requiressecure (). and (). Requireschannel (). Anyrequest (). Requiresinsecure ( ). and (). CSRF (). Disab Le (); //temporarily disable CSRF}
- Test it and see the results. Yes, now you can only open the HTTPS secure channel for requests under the/free/path!
The implementation of the secure access channel is now enabled. Hope to read to the end of your help! If you have a good opinion, please feel free to comment and exchange.
Tomcat8+spring-security One-step implementation of enabling secure channel (HTTPS)