Browse Source

单点登录1

zhuhaiwen 3 years ago
parent
commit
2f4121d6ac

+ 111 - 0
oa-app/src/main/java/com/css/oa/config/CasConfiguration.java

@ -0,0 +1,111 @@
1
package com.css.oa.config;
2
3
import org.jasig.cas.client.authentication.AuthenticationFilter;
4
import org.jasig.cas.client.configuration.ConfigurationKeys;
5
import org.jasig.cas.client.session.SingleSignOutFilter;
6
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
7
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
8
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
9
import org.springframework.beans.factory.annotation.Autowired;
10
import org.springframework.boot.context.properties.EnableConfigurationProperties;
11
import org.springframework.boot.web.servlet.FilterRegistrationBean;
12
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
13
import org.springframework.context.annotation.Bean;
14
import org.springframework.context.annotation.Configuration;
15
16
import javax.servlet.http.HttpSessionListener;
17
18
@Configuration
19
@EnableConfigurationProperties(CasConfigurationProperties.class)
20
public class CasConfiguration {
21
    @Autowired
22
    private CasConfigurationProperties autoconfig;
23
24
    @Bean
25
    public ServletListenerRegistrationBean<HttpSessionListener> httpSessionListener() {
26
        ServletListenerRegistrationBean<HttpSessionListener> listener = new ServletListenerRegistrationBean<>();
27
        listener.setListener(new SingleSignOutHttpSessionListener());
28
        return listener;
29
    }
30
31
    /**
32
     * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前
33
     */
34
    @Bean
35
    public FilterRegistrationBean singleSignOutFilter() {
36
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
37
        filterRegistration.setFilter(new SingleSignOutFilter());
38
        filterRegistration.addUrlPatterns("/*");
39
40
        filterRegistration.addInitParameter(ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName(), autoconfig.getCasServerUrlPrefix());
41
        filterRegistration.addInitParameter(ConfigurationKeys.SERVER_NAME.getName(), autoconfig.getServerName());
42
        filterRegistration.setOrder(1);
43
        return filterRegistration;
44
    }
45
46
    /**
47
     * 该过滤器负责用户的认证工作
48
     */
49
    @Bean
50
    public FilterRegistrationBean authenticationFilter() {
51
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
52
        filterRegistration.setFilter(new AuthenticationFilter());
53
        filterRegistration.addUrlPatterns("/*");
54
55
        filterRegistration.addInitParameter(ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), autoconfig.getCasServerLoginUrl());
56
        filterRegistration.addInitParameter(ConfigurationKeys.SERVER_NAME.getName(), autoconfig.getServerName());
57
        filterRegistration.addInitParameter(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE.getName(), autoconfig.getIgnoreUrlPatternType());
58
        filterRegistration.addInitParameter(ConfigurationKeys.IGNORE_PATTERN.getName(), autoconfig.getIgnorePattern());
59
        filterRegistration.setOrder(2);
60
        return filterRegistration;
61
    }
62
63
    /**
64
     * 该过滤器负责对Ticket的校验工作
65
     */
66
    @Bean
67
    public FilterRegistrationBean cas30ProxyReceivingTicketValidationFilter() {
68
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
69
        filterRegistration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
70
        filterRegistration.addUrlPatterns("/*");
71
72
        filterRegistration.addInitParameter(ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName(), autoconfig.getCasServerUrlPrefix());
73
        filterRegistration.addInitParameter(ConfigurationKeys.SERVER_NAME.getName(), autoconfig.getServerName());
74
        filterRegistration.addInitParameter(ConfigurationKeys.REDIRECT_AFTER_VALIDATION.getName(), String.valueOf(autoconfig.isRedirectAfterValidation()));
75
        filterRegistration.addInitParameter(ConfigurationKeys.USE_SESSION.getName(), String.valueOf(autoconfig.isUseSession()));
76
        filterRegistration.addInitParameter(ConfigurationKeys.ENCODING.getName(), autoconfig.getEncoding());
77
        filterRegistration.setOrder(3);
78
        return filterRegistration;
79
    }
80
81
    /**
82
     * 该过滤器对HttpServletRequest请求包装,
83
     * 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名
84
     */
85
    @Bean
86
    public FilterRegistrationBean httpServletRequestWrapperFilter() {
87
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
88
        filterRegistration.setFilter(new HttpServletRequestWrapperFilter());
89
        filterRegistration.addUrlPatterns("/*");
90
91
        filterRegistration.setOrder(4);
92
        return filterRegistration;
93
    }
94
95
    /**
96
     * 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
97
     * 比如AssertionHolder.getAssertion().getPrincipal().getName()。
98
     * 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息
99
     */
100
    /*@Bean
101
    public FilterRegistrationBean assertionThreadLocalFilter() {
102
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
103
        filterRegistration.setFilter(new AssertionThreadLocalFilter());
104
        filterRegistration.addUrlPatterns("/*");
105
        filterRegistration.setOrder(5);
106
        return filterRegistration;
107
    }*/
108
109
110
111
}

+ 308 - 0
oa-app/src/main/java/com/css/oa/config/CasConfigurationProperties.java

@ -0,0 +1,308 @@
1
package com.css.oa.config;
2
3
import org.springframework.boot.context.properties.ConfigurationProperties;
4
5
/**
6
 * SingleSignOutFilter 配置如下:
7
 * <table>
8
 * <thead>
9
 * <tr>
10
 * <th>Property</th>
11
 * <th>Description</th>
12
 * <th>Required</th>
13
 * </tr>
14
 * </thead>
15
 * <tbody>
16
 * <tr>
17
 * <td><code>artifactParameterName</code></td>
18
 * <td>The ticket artifact parameter name. Defaults to <code>ticket</code></td>
19
 * <td>No</td>
20
 * </tr>
21
 * <tr>
22
 * <td><code>logoutParameterName</code></td>
23
 * <td>Defaults to <code>logoutRequest</code></td>
24
 * <td>No</td>
25
 * </tr>
26
 * <tr>
27
 * <td><code>frontLogoutParameterName</code></td>
28
 * <td>Defaults to <code>SAMLRequest</code></td>
29
 * <td>No</td>
30
 * </tr>
31
 * <tr>
32
 * <td><code>relayStateParameterName</code></td>
33
 * <td>Defaults to <code>RelayState</code></td>
34
 * <td>No</td>
35
 * </tr>
36
 * <tr>
37
 * <td><code>eagerlyCreateSessions</code></td>
38
 * <td>Defaults to <code>true</code></td>
39
 * <td>No</td>
40
 * </tr>
41
 * <tr>
42
 * <td><code>artifactParameterOverPost</code></td>
43
 * <td>Defaults to  <code>false</code></td>
44
 * <td>No</td>
45
 * </tr>
46
 * <tr>
47
 * <td><code>casServerUrlPrefix</code></td>
48
 * <td>URL to root of CAS Web application context.</td>
49
 * <td>Yes</td>
50
 * </tr></tbody></table>
51
 * --------------------------------------------</br>
52
 * AuthenticationFilter 配置如下:
53
 * <table>
54
 * <thead>
55
 * <tr>
56
 * <th>Property</th>
57
 * <th>Description</th>
58
 * <th>Required</th>
59
 * </tr>
60
 * </thead>
61
 * <tbody>
62
 * <tr>
63
 * <td><code>casServerLoginUrl</code></td>
64
 * <td>Defines the location of the CAS server login URL, i.e. <code>https://localhost:8443/cas/login</code></td>
65
 * <td>Yes</td>
66
 * </tr>
67
 * <tr>
68
 * <td><code>serverName</code></td>
69
 * <td>The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. <a href="https://localhost:8443" rel="nofollow">https://localhost:8443</a> (you must include the protocol, but port is optional if it's a standard port).</td>
70
 * <td>Yes</td>
71
 * </tr>
72
 * <tr>
73
 * <td><code>service</code></td>
74
 * <td>The service URL to send to the CAS server, i.e. <code>https://localhost:8443/yourwebapp/index.html</code></td>
75
 * <td>No</td>
76
 * </tr>
77
 * <tr>
78
 * <td><code>renew</code></td>
79
 * <td>specifies whether <code>renew=true</code> should be sent to the CAS server. Valid values are either <code>true/false</code> (or no value at all). Note that <code>renew</code> cannot be specified as local <code>init-param</code> setting.</td>
80
 * <td>No</td>
81
 * </tr>
82
 * <tr>
83
 * <td><code>gateway</code></td>
84
 * <td>specifies whether <code>gateway=true</code> should be sent to the CAS server. Valid values are either <code>true/false</code> (or no value at all)</td>
85
 * <td>No</td>
86
 * </tr>
87
 * <tr>
88
 * <td><code>artifactParameterName</code></td>
89
 * <td>specifies the name of the request parameter on where to find the artifact (i.e. <code>ticket</code>).</td>
90
 * <td>No</td>
91
 * </tr>
92
 * <tr>
93
 * <td><code>serviceParameterName</code></td>
94
 * <td>specifies the name of the request parameter on where to find the service (i.e. <code>service</code>)</td>
95
 * <td>No</td>
96
 * </tr>
97
 * <tr>
98
 * <td><code>encodeServiceUrl</code></td>
99
 * <td>Whether the client should auto encode the service url. Defaults to <code>true</code></td>
100
 * <td>No</td>
101
 * </tr>
102
 * <tr>
103
 * <td><code>ignorePattern</code></td>
104
 * <td>Defines the url pattern to ignore, when intercepting authentication requests.</td>
105
 * <td>No</td>
106
 * </tr>
107
 * <tr>
108
 * <td><code>ignoreUrlPatternType</code></td>
109
 * <td>Defines the type of the pattern specified. Defaults to <code>REGEX</code>. Other types are <code>CONTAINS</code>, <code>EXACT</code>.</td>
110
 * <td>No</td>
111
 * </tr>
112
 * <tr>
113
 * <td><code>gatewayStorageClass</code></td>
114
 * <td>The storage class used to record gateway requests</td>
115
 * <td>No</td>
116
 * </tr>
117
 * <tr>
118
 * <td><code>authenticationRedirectStrategyClass</code></td>
119
 * <td>The class name of the component to decide how to handle authn redirects to CAS</td>
120
 * <td>No</td>
121
 * </tr></tbody></table>
122
 * <p>
123
 * ---------------------------------------------------<br/>
124
 * Cas20ProxyReceivingTicketValidationFilter 配置如下:
125
 * <table>
126
 * <thead>
127
 * <tr>
128
 * <th>Property</th>
129
 * <th>Description</th>
130
 * <th>Required</th>
131
 * </tr>
132
 * </thead>
133
 * <tbody>
134
 * <tr>
135
 * <td><code>casServerUrlPrefix</code></td>
136
 * <td>The start of the CAS server URL, i.e. <code>https://localhost:8443/cas</code></td>
137
 * <td>Yes</td>
138
 * </tr>
139
 * <tr>
140
 * <td><code>serverName</code></td>
141
 * <td>The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. <code>https://localhost:8443</code> (you must include the protocol, but port is optional if it's a standard port).</td>
142
 * <td>Yes</td>
143
 * </tr>
144
 * <tr>
145
 * <td><code>renew</code></td>
146
 * <td>Specifies whether <code>renew=true</code> should be sent to the CAS server. Valid values are either <code>true/false</code> (or no value at all). Note that <code>renew</code> cannot be specified as local <code>init-param</code> setting.</td>
147
 * <td>No</td>
148
 * </tr>
149
 * <tr>
150
 * <td><code>redirectAfterValidation</code></td>
151
 * <td>Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to <code>true</code>.</td>
152
 * <td>No</td>
153
 * </tr>
154
 * <tr>
155
 * <td><code>useSession</code></td>
156
 * <td>Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to <code>true</code>.</td>
157
 * <td>No</td>
158
 * </tr>
159
 * <tr>
160
 * <td><code>exceptionOnValidationFailure</code></td>
161
 * <td>whether to throw an exception or not on ticket validation failure. Defaults to <code>true</code></td>
162
 * <td>No</td>
163
 * </tr>
164
 * <tr>
165
 * <td><code>proxyReceptorUrl</code></td>
166
 * <td>The URL to watch for <code>PGTIOU/PGT</code> responses from the CAS server. Should be defined from the root of the context. For example, if your application is deployed in <code>/cas-client-app</code> and you want the proxy receptor URL to be <code>/cas-client-app/my/receptor</code> you need to configure proxyReceptorUrl to be <code>/my/receptor</code>.</td>
167
 * <td>No</td>
168
 * </tr>
169
 * <tr>
170
 * <td><code>acceptAnyProxy</code></td>
171
 * <td>Specifies whether any proxy is OK. Defaults to <code>false</code>.</td>
172
 * <td>No</td>
173
 * </tr>
174
 * <tr>
175
 * <td><code>allowedProxyChains</code></td>
176
 * <td>Specifies the proxy chain. Each acceptable proxy chain should include a space-separated list of URLs (for exact match) or regular expressions of URLs (starting by the <code>^</code> character). Each acceptable proxy chain should appear on its own line.</td>
177
 * <td>No</td>
178
 * </tr>
179
 * <tr>
180
 * <td><code>proxyCallbackUrl</code></td>
181
 * <td>The callback URL to provide the CAS server to accept Proxy Granting Tickets.</td>
182
 * <td>No</td>
183
 * </tr>
184
 * <tr>
185
 * <td><code>proxyGrantingTicketStorageClass</code></td>
186
 * <td>Specify an implementation of the ProxyGrantingTicketStorage class that has a no-arg constructor.</td>
187
 * <td>No</td>
188
 * </tr>
189
 * <tr>
190
 * <td><code>sslConfigFile</code></td>
191
 * <td>A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for <code>protocol</code> which defaults to <code>SSL</code>, <code>keyStoreType</code>, <code>keyStorePath</code>, <code>keyStorePass</code>, <code>keyManagerType</code> which defaults to <code>SunX509</code> and <code>certificatePassword</code>.</td>
192
 * <td>No.</td>
193
 * </tr>
194
 * <tr>
195
 * <td><code>encoding</code></td>
196
 * <td>Specifies the encoding charset the client should use</td>
197
 * <td>No</td>
198
 * </tr>
199
 * <tr>
200
 * <td><code>secretKey</code></td>
201
 * <td>The secret key used by the <code>proxyGrantingTicketStorageClass</code> if it supports encryption.</td>
202
 * <td>No</td>
203
 * </tr>
204
 * <tr>
205
 * <td><code>cipherAlgorithm</code></td>
206
 * <td>The algorithm used by the <code>proxyGrantingTicketStorageClass</code> if it supports encryption. Defaults to <code>DESede</code></td>
207
 * <td>No</td>
208
 * </tr>
209
 * <tr>
210
 * <td><code>millisBetweenCleanUps</code></td>
211
 * <td>Startup delay for the cleanup task to remove expired tickets from the storage. Defaults to <code>60000 msec</code></td>
212
 * <td>No</td>
213
 * </tr>
214
 * <tr>
215
 * <td><code>ticketValidatorClass</code></td>
216
 * <td>Ticket validator class to use/create</td>
217
 * <td>No</td>
218
 * </tr>
219
 * <tr>
220
 * <td><code>hostnameVerifier</code></td>
221
 * <td>Hostname verifier class name, used when making back-channel calls</td>
222
 * <td>No</td>
223
 * </tr></tbody></table>
224
 */
225
@ConfigurationProperties(prefix = "spring.cas")
226
public class CasConfigurationProperties {
227
    private String casServerUrlPrefix = "http://10.1.193.115:8100/cas";
228
    private String casServerLoginUrl = casServerUrlPrefix + "/login";
229
    private String casServerLogoutUrl = casServerUrlPrefix + "/logout";
230
    private String serverName = "http://10.1.176.129:8081/zhbg";
231
    private boolean useSession = true;
232
    private boolean redirectAfterValidation = true;
233
    private String ignorePattern = "\\.(js|img|css)(\\?.*)?$";
234
    private String ignoreUrlPatternType = "REGEX";
235
    private String encoding = "UTF-8";
236
237
    public String getCasServerUrlPrefix() {
238
        return casServerUrlPrefix;
239
    }
240
241
    public void setCasServerUrlPrefix(String casServerUrlPrefix) {
242
        this.casServerUrlPrefix = casServerUrlPrefix;
243
    }
244
245
    public String getCasServerLoginUrl() {
246
        return casServerLoginUrl;
247
    }
248
249
    public void setCasServerLoginUrl(String casServerLoginUrl) {
250
        this.casServerLoginUrl = casServerLoginUrl;
251
    }
252
253
    public String getCasServerLogoutUrl() {
254
        return casServerLogoutUrl;
255
    }
256
257
    public void setCasServerLogoutUrl(String casServerLogoutUrl) {
258
        this.casServerLogoutUrl = casServerLogoutUrl;
259
    }
260
261
    public String getServerName() {
262
        return serverName;
263
    }
264
265
    public void setServerName(String serverName) {
266
        this.serverName = serverName;
267
    }
268
269
    public boolean isUseSession() {
270
        return useSession;
271
    }
272
273
    public void setUseSession(boolean useSession) {
274
        this.useSession = useSession;
275
    }
276
277
    public boolean isRedirectAfterValidation() {
278
        return redirectAfterValidation;
279
    }
280
281
    public void setRedirectAfterValidation(boolean redirectAfterValidation) {
282
        this.redirectAfterValidation = redirectAfterValidation;
283
    }
284
285
    public String getIgnorePattern() {
286
        return ignorePattern;
287
    }
288
289
    public void setIgnorePattern(String ignorePattern) {
290
        this.ignorePattern = ignorePattern;
291
    }
292
293
    public String getIgnoreUrlPatternType() {
294
        return ignoreUrlPatternType;
295
    }
296
297
    public void setIgnoreUrlPatternType(String ignoreUrlPatternType) {
298
        this.ignoreUrlPatternType = ignoreUrlPatternType;
299
    }
300
301
    public String getEncoding() {
302
        return encoding;
303
    }
304
305
    public void setEncoding(String encoding) {
306
        this.encoding = encoding;
307
    }
308
}

+ 75 - 17
oa-app/src/main/java/com/css/oa/config/WebSecurityConfig.java

@ -1,30 +1,88 @@
1 1
package com.css.oa.config;
2 2
3
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
4
import org.jasig.cas.client.util.AbstractCasFilter;
5
import org.jasig.cas.client.validation.AssertionImpl;
6
import org.springframework.beans.factory.annotation.Autowired;
7
import org.springframework.boot.autoconfigure.security.SecurityProperties;
8
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
3 9
import org.springframework.context.annotation.Bean;
4 10
import org.springframework.context.annotation.Configuration;
5
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
6
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
11
import org.springframework.core.annotation.Order;
12
import org.springframework.security.authentication.AnonymousAuthenticationToken;
13
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
14
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
15
import org.springframework.security.config.annotation.web.builders.WebSecurity;
16
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
17
import org.springframework.security.core.Authentication;
18
import org.springframework.security.core.context.SecurityContextHolder;
19
import org.springframework.security.core.userdetails.User;
20
import org.springframework.security.provisioning.UserDetailsManager;
21
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
22
import org.springframework.web.cors.CorsUtils;
23
24
import javax.servlet.ServletException;
25
import javax.servlet.http.HttpServletRequest;
26
import javax.servlet.http.HttpServletResponse;
27
import java.io.IOException;
7 28
8
/**
9
 * @author hjf
10
 * @version V1.0
11
 * @description: TODO
12
 * @date 2019/11/25 11:25
13
 */
14 29
@Configuration
15
public class WebSecurityConfig extends /*WebMvcConfigurationSupport*/WebMvcConfigurerAdapter {
30
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
31
@Order(SecurityProperties.BASIC_AUTH_ORDER)
32
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
33
    @Autowired
34
    private CasConfigurationProperties autoconfig;
35
16 36
    @Bean
17
    public RedisSessionInterceptor getSessionInterceptor(){
18
        return  new RedisSessionInterceptor();
37
    public UserDetailsManager userDetailsService(AuthenticationManagerBuilder auth) throws Exception {
38
        auth.inMemoryAuthentication().withUser("demo").password("demo").roles("USER");
39
        return (UserDetailsManager) auth.getDefaultUserDetailsService();
19 40
    }
41
20 42
    @Override
21
    public void addInterceptors(InterceptorRegistry registry) {
22
       //拦截所有请求
23
       //registry.addInterceptor(getSessionInterceptor()).excludePathPatterns("/login**").addPathPatterns("/**");
24
       //放行所有请求
25
        registry.addInterceptor(getSessionInterceptor()).excludePathPatterns("/**");
43
    public void configure(WebSecurity web) throws Exception {
44
        web.ignoring().antMatchers("/css/**", "/js/**");
45
    }
26 46
27
        super.addInterceptors(registry);
47
    @Override
48
    protected void configure(HttpSecurity http) throws Exception {
49
        http.headers().frameOptions().disable();
50
        http.csrf().disable();
51
        http.httpBasic().disable();
52
        http.formLogin()
53
            .loginPage("/casLogin")
54
            .loginProcessingUrl("/login")
55
            .defaultSuccessUrl("/index")
56
            .successHandler(new SavedRequestAwareAuthenticationSuccessHandler(){
57
                @Override
58
                public void onAuthenticationSuccess(HttpServletRequest request,
59
                                                    HttpServletResponse response, Authentication authentication)
60
                    throws ServletException, IOException {
61
                    super.onAuthenticationSuccess(request, response, authentication);
62
                    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
63
                    if (!(auth instanceof AnonymousAuthenticationToken)) {
64
                        User user = (User) auth.getPrincipal();
65
                        request.getSession().setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, new AssertionImpl(user.getUsername()));
66
                    }
67
                }
68
            })
69
            .permitAll();
70
        http.authorizeRequests()
71
            .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
72
            .antMatchers("/register", "/casLogin").permitAll()
73
            .anyRequest().authenticated();
74
        http.logout()
75
            .logoutUrl("/logout")
76
            .logoutSuccessUrl(autoconfig.getCasServerLogoutUrl() + "?service=" + autoconfig.getServerName() + "/index")
77
            .permitAll();
78
        http.antMatcher("/**");
28 79
    }
29 80
81
    @Bean
82
    public ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> singleSignOutHttpSessionListener(){
83
        ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> servletListenerRegistrationBean =
84
            new ServletListenerRegistrationBean<>();
85
        servletListenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener());
86
        return servletListenerRegistrationBean;
87
    }
30 88
}

+ 22 - 0
oa-app/src/main/java/com/css/oa/exam/admin/bean/LoginUser.java

@ -0,0 +1,22 @@
1
package com.css.oa.exam.admin.bean;
2
3
public class LoginUser {
4
    private String username;
5
    private String password;
6
7
    public String getUsername() {
8
        return username;
9
    }
10
11
    public void setUsername(String username) {
12
        this.username = username;
13
    }
14
15
    public String getPassword() {
16
        return password;
17
    }
18
19
    public void setPassword(String password) {
20
        this.password = password;
21
    }
22
}

+ 64 - 19
oa-app/src/main/java/com/css/oa/exam/admin/controller/AdminController.java

@ -1,34 +1,79 @@
1 1
package com.css.oa.exam.admin.controller;
2 2
3
import com.css.oa.exam.admin.bean.LoginUser;
3 4
import com.css.oa.exam.base.BaseController;
4
import com.css.oa.exam.admin.service.AdminService;
5 5
import io.swagger.annotations.Api;
6 6
import org.springframework.beans.factory.annotation.Autowired;
7
import org.springframework.security.authentication.AnonymousAuthenticationToken;
8
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9
import org.springframework.security.core.Authentication;
10
import org.springframework.security.core.authority.AuthorityUtils;
11
import org.springframework.security.core.context.SecurityContextHolder;
12
import org.springframework.security.core.userdetails.User;
13
import org.springframework.security.core.userdetails.UserDetailsService;
14
import org.springframework.security.provisioning.UserDetailsManager;
15
import org.springframework.ui.Model;
7 16
import org.springframework.web.bind.annotation.*;
8 17
9
@Api(tags = {"模拟切换用户"})
18
import javax.servlet.http.HttpServletRequest;
19
20
@Api(tags = {"管理员登录"})
10 21
@RestController
11 22
@RequestMapping("/admin")
12 23
public class AdminController extends BaseController {
13 24
14 25
    @Autowired
15
    private AdminService mService;
16
17
//    @ApiOperation(value = "增加公告接口")
18
//    @PostMapping("/login")
19
//    public Result login(HttpServletResponse response,
20
//                        @RequestParam("username") String username,
21
//                        @RequestParam("password") String password) {
22
//        Result<Map> result;
23
//        try {
24
//            String token = mService.login(response, username, password);
25
//            result = setResult(token);
26
//        } catch (Exception e) {
27
//            result = setErr(e.getMessage());
28
//            e.printStackTrace();
29
//        }
30
//        return result;
31
//    }
26
    private UserDetailsService userDetailsService;
27
28
    @GetMapping("*")
29
    public String welcome() {
30
        return "redirect:casLogin";
31
    }
32
33
    @GetMapping("index")
34
    public String index() {
35
        return "welcome";
36
    }
37
38
    @GetMapping("login")
39
    public String loginPage(Model model) {
40
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
41
        if (!(auth instanceof AnonymousAuthenticationToken)) {
42
            return "redirect:index";
43
        }
44
        LoginUser user = new LoginUser();
45
        model.addAttribute("user",user);
46
        return "login";
47
    }
48
49
    @GetMapping("casLogin")
50
    public String casLogin(HttpServletRequest request) {
51
        if (request.getRemoteUser() != null) {
52
            Authentication auth = new UsernamePasswordAuthenticationToken(request.getRemoteUser(), request.getRemoteUser(),
53
                    AuthorityUtils.createAuthorityList("USER"));
54
            SecurityContextHolder.getContext().setAuthentication(auth);
55
            return "redirect:index";
56
        }
57
        return "redirect:login";
58
    }
59
60
    @GetMapping("register")
61
    public String registerPage(Model model) {
62
        LoginUser user = new LoginUser();
63
        model.addAttribute("user",user);
64
        return "register";
65
    }
32 66
67
    @PostMapping("register")
68
    public String register(LoginUser user) {
69
        UserDetailsManager userDetailsManager = (UserDetailsManager) userDetailsService;
70
        boolean exists = userDetailsManager.userExists(user.getUsername());
71
        if (!exists) {
72
            userDetailsManager.createUser(new User(user.getUsername(), user.getPassword(), AuthorityUtils.createAuthorityList("USER")));
73
            return "redirect:register?success";
74
        } else {
75
            return "redirect:register?error";
76
        }
77
    }
33 78
34 79
}

+ 20 - 0
pom.xml

@ -50,6 +50,26 @@
50 50
    </properties>
51 51
52 52
    <dependencies>
53
        <dependency>
54
            <groupId>org.jasig.cas.client</groupId>
55
            <artifactId>cas-client-core</artifactId>
56
            <version>3.5.1</version>
57
        </dependency>
58
        <dependency>
59
            <groupId>org.springframework.security</groupId>
60
            <artifactId>spring-security-config</artifactId>
61
            <version>4.1.0.RELEASE</version>
62
        </dependency>
63
        <dependency>
64
            <groupId>org.springframework.security</groupId>
65
            <artifactId>spring-security-core</artifactId>
66
            <version>4.1.0.RELEASE</version>
67
        </dependency>
68
        <dependency>
69
            <groupId>org.springframework.security</groupId>
70
            <artifactId>spring-security-web</artifactId>
71
            <version>4.1.0.RELEASE</version>
72
        </dependency>
53 73
        <!--        llg加的测试依赖-->
54 74
        <dependency>
55 75
            <groupId>junit</groupId>