Это лучшее объяснение, которое я видел. Понимать JavaScripts это с помощью Clarity
Ссылка эта ALLWAYS означает (и содержит значение) объект - особый объект - и он обычно используется внутри функции или метода, хотя он может использоваться вне функции в глобальной области. Обратите внимание, что когда мы используем строгий режим, это содержит значение неопределенных в глобальных функциях и анонимных функциях, которые не привязаны к какому-либо объекту.
blockquote>Существуют четыре условия, в которых это может запутать:
- Когда мы передаем метод (который использует этот ) в качестве параметра, который будет использоваться в качестве функции обратного вызова.
- Другой пример, когда это неправильно понимается, - это когда мы используем внутренний метод (замыкание). Важно отметить, что закрытие не может получить доступ к переменной этой внешней функции внешней функции], используя это ключевое слово, потому что эта переменная доступна только самой функции, а не внутренними функциями.
- Используя этот , когда метод присваивается переменной. Значение этого привязано к другому объекту, если мы назначим метод, который использует это для переменной
- Используя этот при использовании bind, apply и
Он дает примеры кода, объяснения и исправления кода, которые, как я думал, очень полезны.
Проблема состоит в том, что безопасность Spring не делает объекта Аутентификации доступным как боб в контейнере, таким образом, нет никакого способа легко ввести или автосоединить его проводом из поля.
, Прежде чем мы начали использовать безопасность Spring, мы создадим ограниченный по объему сессией боб в контейнере, чтобы сохранить Принципал, ввести это в "AuthenticationService" (одиночный элемент) и затем ввести этот боб на другие службы, для которых было нужно знание текущего Принципала.
при реализации собственной услуги аутентификации Вы могли бы в основном сделать то же самое: создайте ограниченный по объему сессией боб с "основным" свойством, введите это в свою услугу аутентификации, сделайте, чтобы подлинный сервис установил свойство на успешном авторе и затем сделайте подлинный сервис доступным для других бобов, поскольку Вам нужен он.
я не чувствовал бы себя слишком плохо об использовании SecurityContextHolder. все же. Я знаю, что это - помехи / Singleton и что Spring препятствует использованию таких вещей, но их реализация заботится для поведения соответственно в зависимости от среды: ограниченный по объему сессией в контейнере Сервлета, ограниченном по объему потоком в тесте JUnit, и т.д. Реальный ограничивающий фактор Singleton - когда он обеспечивает реализацию, которая негибка к различным средам.
Вы совершенно правы, чтобы быть затронутыми - вызовы статического метода особенно проблематичны для поблочного тестирования, поскольку Вы не можете легко дразнить свои зависимости. То, что я собираюсь показать Вам, - то, как позволить Spring, контейнер МОК делает грязную работу для Вас, оставляя Вас с аккуратным, тестируемым кодом. SecurityContextHolder является классом платформы и в то время как для Вашего кода в системе защиты низкого уровня может быть нормально быть связанным с ним, Вы, вероятно, хотите выставить более опрятный интерфейс своим компонентам UI (т.е. контроллеры).
cliff.meyers упомянул, что один путь вокруг этого - создает Ваш собственный "основной" тип и вводит экземпляр в потребителей. Spring < aop:scoped-прокси /> тег, представленный в 2.x объединенный с бобовым определением объема запроса и поддержкой метода фабрики, может быть билетом к самому читаемому коду.
Это могло работать как следующее:
public class MyUserDetails implements UserDetails {
// this is your custom UserDetails implementation to serve as a principal
// implement the Spring methods and add your own methods as appropriate
}
public class MyUserHolder {
public static MyUserDetails getUserDetails() {
Authentication a = SecurityContextHolder.getContext().getAuthentication();
if (a == null) {
return null;
} else {
return (MyUserDetails) a.getPrincipal();
}
}
}
public class MyUserAwareController {
MyUserDetails currentUser;
public void setCurrentUser(MyUserDetails currentUser) {
this.currentUser = currentUser;
}
// controller code
}
Ничто сложное до сих пор, правильно? На самом деле, вероятно, уже необходимо было сделать большую часть из этого. Затем, в Вашем бобе контекст определяют ограниченный по объему запросом боб для содержания принципала:
<bean id="userDetails" class="MyUserHolder" factory-method="getUserDetails" scope="request">
<aop:scoped-proxy/>
</bean>
<bean id="controller" class="MyUserAwareController">
<property name="currentUser" ref="userDetails"/>
<!-- other props -->
</bean>
Благодаря волшебству aop:scoped-тега-proxy, статический метод getUserDetails назовут каждый раз, когда новый Запрос HTTP входит, и любые ссылки на currentUser свойство будут разрешены правильно. Теперь поблочное тестирование становится тривиальным:
protected void setUp() {
// existing init code
MyUserDetails user = new MyUserDetails();
// set up user as you wish
controller.setCurrentUser(user);
}
Hope это помогает!
Я смотрел бы на абстрактные тестовые классы Spring и фиктивные объекты, с которыми говорят приблизительно здесь . Они обеспечивают мощный способ автосоединить проводом Ваши управляемые объекты Spring, делающие поблочное и легче интеграционное тестирование.
Я сам задал тот же вопрос в здесь и только что опубликовал ответ, который недавно нашел. Короткий ответ: введите SecurityContext
и обратитесь к SecurityContextHolder
только в конфигурации Spring, чтобы получить SecurityContext
Использование статики в данном случае - лучший способ написания безопасного кода.
Да, статика, как правило, плохая, но в данном случае статика - это то, что вам нужно. Так как контекст безопасности ассоциирует Принципала с текущим потоком, наиболее безопасный код будет обращаться к статическому из потока как можно более непосредственно. Скрытие доступа за классом обертки, который вводится, дает злоумышленнику больше точек для атаки. Им не нужен будет доступ к коду (который им будет сложно изменить, если банку подписать), им просто нужен способ переопределить конфигурацию, что можно сделать во время выполнения или просунуть немного XML в classpath. Даже использование впрыска аннотаций было бы переопределяемым с помощью внешнего XML. Такой XML мог бы впрыскивать работающую систему с неуправляемым принципом.
dbsize
. – RichVel 15 August 2013 в 07:00