Общепринятой практикой является возобновление сеанса HTTP при входе в систему пользователя. Это заставит новый идентификатор сеанса, избегая уязвимостей фиксации сеанса.
Есть ли предпочтительный шаблон для реализации этого с CDI, когда задействованы компоненты @SessionScoped? Сложность состоит в том, что, сделав недействительным текущий сеанс HTTP, вы получите другой bean-объект сессионной области со следующим запросом, но не до следующего запроса.
Например, предположим, что сессионный компонент для хранения пользователя информация для входа в систему:
@Named("sessionbean")
@SessionScoped
public class SessionBean implements Serializable {
private int userId;
private String username;
private List<String> privileges;
// Accessors omitted
}
И еще один bean-компонент для управления входом в систему:
@Named("loginbean")
@ViewScoped
public class LoginBean implements Serializable {
private String username;
private String password;
@Inject private SessionBean session;
@Inject private SessionManager sessionManager;
@Inject private PrivilegeManager privilegeManager;
public String doLogin() {
String destinationUrl;
if (validate(username, password)) {
FacesContext context = FacesContext.getCurrentInstance();
// force renewal of HTTP session
context.getExternalContext().invalidateSession();
// retrieve new session bean ** No longer works with CDI **
Application app = context.getApplication();
session = app.evaluateExpressionGet(context, "#{sessionbean}", SessionBean.class);
session.setUsername(username);
session.setSessionId(sessionManager.createNewSession(username));
session.setPrivileges(privilegeManager.getPrivileges(username));
destinationUrl = createLandingPageUrl();
} else {
destinationUrl = createFailureUrl("Unknown user or password");
}
return destinationUrl;
}
}
Для Managed Beans это приведет к получению нового SessionBean, но для CDI приведенный выше код просто вернет тот же SessionBean. Любые рекомендации или умные идеи?