Saya relatif baru dalam keamanan Musim Semi dan Musim Semi.
Saya mencoba untuk menulis program di mana saya perlu mengautentikasi pengguna di ujung server menggunakan keamanan Spring,
Saya datang dengan yang berikut:
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
throws AuthenticationException
{
System.out.println("Method invoked : additionalAuthenticationChecks isAuthenticated ? :"+usernamePasswordAuthenticationToken.isAuthenticated());
}
@Override
protected UserDetails retrieveUser(String username,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException
{
System.out.println("Method invoked : retrieveUser");
//so far so good, i can authenticate user here, and throw exception if not authenticated!!
//THIS IS WHERE I WANT TO ACCESS SESSION OBJECT
}
}
Kasus penggunaan saya adalah ketika pengguna diautentikasi, saya perlu menempatkan atribut seperti:
session.setAttribute("userObject", myUserObject);
myUserObject adalah objek dari beberapa kelas yang dapat saya akses di seluruh kode server saya di beberapa permintaan pengguna.
sumber
<listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>
Karena Anda menggunakan Spring, tetap gunakan Spring, jangan meretasnya sendiri seperti pos lainnya.
The pengguna Musim Semi mengatakan:
Praktik terbaik yang disarankan untuk mengakses sesi ini adalah:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
Kuncinya di sini adalah Keamanan Musim Semi dan Musim Semi melakukan segala macam hal hebat untuk Anda seperti Pencegahan Fiksasi Sesi. Hal-hal ini mengasumsikan bahwa Anda menggunakan framework Spring sebagaimana yang dirancang untuk digunakan. Jadi, di servlet Anda, buatlah context aware dan akses sesi seperti contoh di atas.
Jika Anda hanya perlu menyimpan beberapa data dalam cakupan sesi, coba buat kacang cakupan sesi seperti contoh ini dan biarkan autowire melakukan keajaibannya. :)
sumber
saya membuat utilitas saya sendiri. itu berguna. :)
package samples.utils; import java.util.Arrays; import java.util.Collection; import java.util.Locale; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.MessageSource; import org.springframework.core.convert.ConversionService; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.ui.context.Theme; import org.springframework.util.ClassUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.ThemeResolver; import org.springframework.web.servlet.support.RequestContextUtils; /** * SpringMVC通用工具 * * @author 应卓(yingzhor@gmail.com) * */ public final class WebContextHolder { private static final Logger LOGGER = LoggerFactory.getLogger(WebContextHolder.class); private static WebContextHolder INSTANCE = new WebContextHolder(); public WebContextHolder get() { return INSTANCE; } private WebContextHolder() { super(); } // -------------------------------------------------------------------------------------------------------------- public HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); return attributes.getRequest(); } public HttpSession getSession() { return getSession(true); } public HttpSession getSession(boolean create) { return getRequest().getSession(create); } public String getSessionId() { return getSession().getId(); } public ServletContext getServletContext() { return getSession().getServletContext(); // servlet2.3 } public Locale getLocale() { return RequestContextUtils.getLocale(getRequest()); } public Theme getTheme() { return RequestContextUtils.getTheme(getRequest()); } public ApplicationContext getApplicationContext() { return WebApplicationContextUtils.getWebApplicationContext(getServletContext()); } public ApplicationEventPublisher getApplicationEventPublisher() { return (ApplicationEventPublisher) getApplicationContext(); } public LocaleResolver getLocaleResolver() { return RequestContextUtils.getLocaleResolver(getRequest()); } public ThemeResolver getThemeResolver() { return RequestContextUtils.getThemeResolver(getRequest()); } public ResourceLoader getResourceLoader() { return (ResourceLoader) getApplicationContext(); } public ResourcePatternResolver getResourcePatternResolver() { return (ResourcePatternResolver) getApplicationContext(); } public MessageSource getMessageSource() { return (MessageSource) getApplicationContext(); } public ConversionService getConversionService() { return getBeanFromApplicationContext(ConversionService.class); } public DataSource getDataSource() { return getBeanFromApplicationContext(DataSource.class); } public Collection<String> getActiveProfiles() { return Arrays.asList(getApplicationContext().getEnvironment().getActiveProfiles()); } public ClassLoader getBeanClassLoader() { return ClassUtils.getDefaultClassLoader(); } private <T> T getBeanFromApplicationContext(Class<T> requiredType) { try { return getApplicationContext().getBean(requiredType); } catch (NoUniqueBeanDefinitionException e) { LOGGER.error(e.getMessage(), e); throw e; } catch (NoSuchBeanDefinitionException e) { LOGGER.warn(e.getMessage()); return null; } } }
sumber
Memang Anda bisa mengakses informasi dari sesi bahkan ketika sesi sedang dihancurkan di HttpSessionLisener dengan melakukan:
public void sessionDestroyed(HttpSessionEvent hse) { SecurityContextImpl sci = (SecurityContextImpl) hse.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); // be sure to check is not null since for users who just get into the home page but never get authenticated it will be if (sci != null) { UserDetails cud = (UserDetails) sci.getAuthentication().getPrincipal(); // do whatever you need here with the UserDetails } }
atau Anda juga dapat mengakses informasi di mana pun Anda memiliki objek HttpSession yang tersedia seperti:
SecurityContextImpl sci = (SecurityContextImpl) session().getAttribute("SPRING_SECURITY_CONTEXT");
asumsi terakhir Anda memiliki sesuatu seperti:
HttpSession sesssion = ...; // can come from request.getSession(false);
sumber
Saya mencoba dengan kode berikutnya dan bekerja dengan sangat baik
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * Created by jaime on 14/01/15. */ @Controller public class obteinUserSession { @RequestMapping(value = "/loginds", method = RequestMethod.GET) public String UserSession(ModelMap modelMap) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); String name = auth.getName(); modelMap.addAttribute("username", name); return "hellos " + name; }
sumber
Jika yang Anda butuhkan hanyalah detail Pengguna, untuk Spring Version 4.x Anda dapat menggunakan
@AuthenticationPrincipal
dan@EnableWebSecurity
tag yang disediakan oleh Spring seperti gambar di bawah ini.Kelas Konfigurasi Keamanan:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }
Metode pengontrol:
@RequestMapping("/messages/inbox") public ModelAndView findMessagesForUser(@AuthenticationPrincipal User user) { ... }
sumber
Dalam skenario saya, saya telah menyuntikkan HttpSession ke kelas CustomAuthenticationProvider seperti ini
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{ @Autowired private HttpSession httpSession; @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException { System.out.println("Method invoked : additionalAuthenticationChecks isAuthenticated ? :"+usernamePasswordAuthenticationToken.isAuthenticated()); } @Override protected UserDetails retrieveUser(String username,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { System.out.println("Method invoked : retrieveUser"); //so far so good, i can authenticate user here, and throw exception if not authenticated!! //THIS IS WHERE I WANT TO ACCESS SESSION OBJECT httpSession.setAttribute("userObject", myUserObject); } }
sumber
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); attr.getSessionId();
sumber