Skip to content

Commit bd99b72

Browse files
author
Eugen
committed
Merge pull request eugenp#201 from Doha2012/master
spring oauth auto login
2 parents e1bbbde + a99098b commit bd99b72

File tree

8 files changed

+120
-10
lines changed

8 files changed

+120
-10
lines changed

spring-security-oauth/src/main/java/org/baeldung/config/SecurityConfig.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ protected void configure(HttpSecurity http) throws Exception {
3131
.authorizeRequests()
3232
.antMatchers("/home.html","/post","/postSchedule","/posts").hasRole("USER")
3333
.and()
34-
.httpBasic().authenticationEntryPoint(oauth2AuthenticationEntryPoint());
35-
34+
.httpBasic().authenticationEntryPoint(oauth2AuthenticationEntryPoint())
35+
.and()
36+
.logout()
37+
.deleteCookies("JSESSIONID","CustomRememberMe")
38+
.logoutUrl("/logout")
39+
.logoutSuccessUrl("/");
3640
// @formatter:on
3741
}
3842

spring-security-oauth/src/main/java/org/baeldung/config/SessionListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class SessionListener implements HttpSessionListener {
1313
@Override
1414
public void sessionCreated(HttpSessionEvent event) {
1515
logger.info("==== Session is created ====");
16-
event.getSession().setMaxInactiveInterval(30 * 60);
16+
event.getSession().setMaxInactiveInterval(1 * 60);
1717
event.getSession().setAttribute("PREDICTION_FEATURE", MyFeatures.PREDICTION_FEATURE);
1818
}
1919

spring-security-oauth/src/main/java/org/baeldung/config/WebConfig.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Arrays;
66
import java.util.List;
77

8+
import org.baeldung.persistence.service.RedditTokenService;
89
import org.baeldung.reddit.classifier.RedditClassifier;
910
import org.baeldung.reddit.util.UserAgentInterceptor;
1011
import org.baeldung.web.schedule.ScheduledTasks;
@@ -131,15 +132,16 @@ public OAuth2ProtectedResourceDetails reddit() {
131132
}
132133

133134
@Bean
134-
public OAuth2RestTemplate redditRestTemplate(OAuth2ClientContext clientContext) {
135+
public OAuth2RestTemplate redditRestTemplate(OAuth2ClientContext clientContext, RedditTokenService redditTokenService) {
135136
final OAuth2RestTemplate template = new OAuth2RestTemplate(reddit(), clientContext);
136137
final List<ClientHttpRequestInterceptor> list = new ArrayList<ClientHttpRequestInterceptor>();
137138
list.add(new UserAgentInterceptor());
138139
template.setInterceptors(list);
139-
final AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(new MyAuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(),
140+
final AccessTokenProviderChain accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(new MyAuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(),
140141
new ClientCredentialsAccessTokenProvider()));
142+
accessTokenProvider.setClientTokenServices(redditTokenService);
141143
template.setAccessTokenProvider(accessTokenProvider);
142144
return template;
143145
}
144146
}
145-
}
147+
}

spring-security-oauth/src/main/java/org/baeldung/persistence/dao/UserRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
88
User findByUsername(String username);
99

1010
User findByAccessToken(String token);
11+
12+
User findByRememberMeToken(String token);
1113
}

spring-security-oauth/src/main/java/org/baeldung/persistence/model/User.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class User {
2626

2727
private boolean needCaptcha;
2828

29+
private String rememberMeToken;
30+
2931
public User() {
3032
super();
3133
}
@@ -80,6 +82,14 @@ public void setNeedCaptcha(final boolean needCaptcha) {
8082

8183
//
8284

85+
public String getRememberMeToken() {
86+
return rememberMeToken;
87+
}
88+
89+
public void setRememberMeToken(String rememberMeToken) {
90+
this.rememberMeToken = rememberMeToken;
91+
}
92+
8393
@Override
8494
public int hashCode() {
8595
final int prime = 31;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package org.baeldung.persistence.service;
2+
3+
import org.baeldung.persistence.dao.UserRepository;
4+
import org.baeldung.persistence.model.User;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.security.core.Authentication;
9+
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
10+
import org.springframework.security.oauth2.client.token.ClientTokenServices;
11+
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
12+
import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken;
13+
import org.springframework.security.oauth2.common.OAuth2AccessToken;
14+
import org.springframework.stereotype.Component;
15+
16+
@Component
17+
public class RedditTokenService implements ClientTokenServices {
18+
19+
@Autowired
20+
private UserRepository userReopsitory;
21+
22+
private final Logger logger = LoggerFactory.getLogger(getClass());
23+
24+
public RedditTokenService() {
25+
super();
26+
}
27+
28+
@Override
29+
public OAuth2AccessToken getAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {
30+
logger.info("reddit ==== getAccessToken");
31+
final User user = (User) authentication.getPrincipal();
32+
final DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(user.getAccessToken());
33+
token.setRefreshToken(new DefaultOAuth2RefreshToken((user.getRefreshToken())));
34+
token.setExpiration(user.getTokenExpiration());
35+
return token;
36+
}
37+
38+
@Override
39+
public void saveAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication, OAuth2AccessToken accessToken) {
40+
logger.info("reddit ==== saveAccessToken");
41+
final User user = (User) authentication.getPrincipal();
42+
user.setAccessToken(accessToken.getValue());
43+
if (accessToken.getRefreshToken() != null) {
44+
user.setRefreshToken(accessToken.getRefreshToken().getValue());
45+
}
46+
user.setTokenExpiration(accessToken.getExpiration());
47+
userReopsitory.save(user);
48+
}
49+
50+
@Override
51+
public void removeAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {
52+
logger.info("reddit ==== removeAccessToken");
53+
}
54+
55+
}

spring-security-oauth/src/main/java/org/baeldung/web/RedditController.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
import java.util.List;
99
import java.util.Map;
1010

11+
import javax.servlet.http.Cookie;
12+
import javax.servlet.http.HttpServletRequest;
13+
import javax.servlet.http.HttpServletResponse;
14+
15+
import org.apache.commons.lang.RandomStringUtils;
1116
import org.baeldung.persistence.dao.PostRepository;
1217
import org.baeldung.persistence.dao.UserRepository;
1318
import org.baeldung.persistence.model.Post;
@@ -27,6 +32,7 @@
2732
import org.springframework.ui.Model;
2833
import org.springframework.util.LinkedMultiValueMap;
2934
import org.springframework.util.MultiValueMap;
35+
import org.springframework.web.bind.annotation.CookieValue;
3036
import org.springframework.web.bind.annotation.PathVariable;
3137
import org.springframework.web.bind.annotation.RequestMapping;
3238
import org.springframework.web.bind.annotation.RequestMethod;
@@ -43,6 +49,7 @@ public class RedditController {
4349

4450
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
4551
private final SimpleDateFormat dfHour = new SimpleDateFormat("HH");
52+
public static final String REMEMBER_ME_COOKIE = "CustomRememberMe";
4653

4754
@Autowired
4855
private OAuth2RestTemplate redditRestTemplate;
@@ -57,9 +64,11 @@ public class RedditController {
5764
private RedditClassifier redditClassifier;
5865

5966
@RequestMapping("/login")
60-
public final String redditLogin() {
61-
final JsonNode node = redditRestTemplate.getForObject("https://oauth.reddit.com/api/v1/me", JsonNode.class);
62-
loadAuthentication(node.get("name").asText(), redditRestTemplate.getAccessToken());
67+
public final String redditLogin(@CookieValue(value = REMEMBER_ME_COOKIE, required = false) String rememberMe, HttpServletRequest request, HttpServletResponse response) {
68+
if (!canAutoLogin(rememberMe)) {
69+
final JsonNode node = redditRestTemplate.getForObject("https://oauth.reddit.com/api/v1/me", JsonNode.class);
70+
loadAuthentication(node.get("name").asText(), redditRestTemplate.getAccessToken(), response);
71+
}
6372
return "redirect:home.html";
6473
}
6574

@@ -221,7 +230,7 @@ private final String parseResponse(final JsonNode node) {
221230
}
222231
}
223232

224-
private final void loadAuthentication(final String name, final OAuth2AccessToken token) {
233+
private void loadAuthentication(final String name, final OAuth2AccessToken token, HttpServletResponse response) {
225234
User user = userReopsitory.findByUsername(name);
226235
if (user == null) {
227236
user = new User();
@@ -239,8 +248,35 @@ private final void loadAuthentication(final String name, final OAuth2AccessToken
239248
user.setTokenExpiration(token.getExpiration());
240249
userReopsitory.save(user);
241250

251+
generateRememberMeToken(user, response);
252+
242253
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, token.getValue(), Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
243254
SecurityContextHolder.getContext().setAuthentication(auth);
244255
}
245256

257+
private void generateRememberMeToken(User user, HttpServletResponse response) {
258+
String rememberMe = RandomStringUtils.randomAlphanumeric(30);
259+
while (userReopsitory.findByRememberMeToken(rememberMe) != null) {
260+
rememberMe = RandomStringUtils.randomAlphanumeric(30);
261+
}
262+
user.setRememberMeToken(rememberMe);
263+
userReopsitory.save(user);
264+
final Cookie c = new Cookie(REMEMBER_ME_COOKIE, rememberMe);
265+
c.setMaxAge(1209600);
266+
response.addCookie(c);
267+
}
268+
269+
private boolean canAutoLogin(String rememberMeToken) {
270+
if (rememberMeToken != null) {
271+
final User user = userReopsitory.findByRememberMeToken(rememberMeToken);
272+
if (user != null) {
273+
logger.info("Auto Login successfully");
274+
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getAccessToken(), Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
275+
SecurityContextHolder.getContext().setAuthentication(auth);
276+
return true;
277+
}
278+
}
279+
return false;
280+
}
281+
246282
}

spring-security-oauth/src/main/webapp/WEB-INF/jsp/home.jsp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
<p class="navbar-text navbar-right">Logged in as
1818
<b><sec:authentication property="principal.username" /></b>&nbsp;&nbsp;&nbsp;
19+
<a href="logout">Logout</a>&nbsp;&nbsp;&nbsp;
1920
</p>
2021

2122
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

0 commit comments

Comments
 (0)